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 */
017 package org.apache.commons.collections.functors;
018
019 import java.io.Serializable;
020
021 import org.apache.commons.collections.Closure;
022 import org.apache.commons.collections.Predicate;
023
024 /**
025 * Closure implementation that executes a closure repeatedly until a condition is met,
026 * like a do-while or while loop.
027 *
028 * @since Commons Collections 3.0
029 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
030 *
031 * @author Stephen Colebourne
032 */
033 public class WhileClosure implements Closure, Serializable {
034
035 /** Serial version UID */
036 private static final long serialVersionUID = -3110538116913760108L;
037
038 /** The test condition */
039 private final Predicate iPredicate;
040 /** The closure to call */
041 private final Closure iClosure;
042 /** The flag, true is a do loop, false is a while */
043 private final boolean iDoLoop;
044
045 /**
046 * Factory method that performs validation.
047 *
048 * @param predicate the predicate used to evaluate when the loop terminates, not null
049 * @param closure the closure the execute, not null
050 * @param doLoop true to act as a do-while loop, always executing the closure once
051 * @return the <code>while</code> closure
052 * @throws IllegalArgumentException if the predicate or closure is null
053 */
054 public static Closure getInstance(Predicate predicate, Closure closure, boolean doLoop) {
055 if (predicate == null) {
056 throw new IllegalArgumentException("Predicate must not be null");
057 }
058 if (closure == null) {
059 throw new IllegalArgumentException("Closure must not be null");
060 }
061 return new WhileClosure(predicate, closure, doLoop);
062 }
063
064 /**
065 * Constructor that performs no validation.
066 * Use <code>getInstance</code> if you want that.
067 *
068 * @param predicate the predicate used to evaluate when the loop terminates, not null
069 * @param closure the closure the execute, not null
070 * @param doLoop true to act as a do-while loop, always executing the closure once
071 */
072 public WhileClosure(Predicate predicate, Closure closure, boolean doLoop) {
073 super();
074 iPredicate = predicate;
075 iClosure = closure;
076 iDoLoop = doLoop;
077 }
078
079 /**
080 * Executes the closure until the predicate is false.
081 *
082 * @param input the input object
083 */
084 public void execute(Object input) {
085 if (iDoLoop) {
086 iClosure.execute(input);
087 }
088 while (iPredicate.evaluate(input)) {
089 iClosure.execute(input);
090 }
091 }
092
093 /**
094 * Gets the predicate in use.
095 *
096 * @return the predicate
097 * @since Commons Collections 3.1
098 */
099 public Predicate getPredicate() {
100 return iPredicate;
101 }
102
103 /**
104 * Gets the closure.
105 *
106 * @return the closure
107 * @since Commons Collections 3.1
108 */
109 public Closure getClosure() {
110 return iClosure;
111 }
112
113 /**
114 * Is the loop a do-while loop.
115 *
116 * @return true is do-while, false if while
117 * @since Commons Collections 3.1
118 */
119 public boolean isDoLoop() {
120 return iDoLoop;
121 }
122
123 }