001: /*
002: * Copyright 2001-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.functors;
017:
018: import java.io.Serializable;
019:
020: import org.apache.commons.collections.Closure;
021: import org.apache.commons.collections.Predicate;
022:
023: /**
024: * Closure implementation that executes a closure repeatedly until a condition is met,
025: * like a do-while or while loop.
026: *
027: * @since Commons Collections 3.0
028: * @version $Revision: 348444 $ $Date: 2005-11-23 14:06:56 +0000 (Wed, 23 Nov 2005) $
029: *
030: * @author Stephen Colebourne
031: */
032: public class WhileClosure implements Closure, Serializable {
033:
034: /** Serial version UID */
035: private static final long serialVersionUID = -3110538116913760108L;
036:
037: /** The test condition */
038: private final Predicate iPredicate;
039: /** The closure to call */
040: private final Closure iClosure;
041: /** The flag, true is a do loop, false is a while */
042: private final boolean iDoLoop;
043:
044: /**
045: * Factory method that performs validation.
046: *
047: * @param predicate the predicate used to evaluate when the loop terminates, not null
048: * @param closure the closure the execute, not null
049: * @param doLoop true to act as a do-while loop, always executing the closure once
050: * @return the <code>while</code> closure
051: * @throws IllegalArgumentException if the predicate or closure is null
052: */
053: public static Closure getInstance(Predicate predicate,
054: Closure closure, boolean doLoop) {
055: if (predicate == null) {
056: throw new IllegalArgumentException(
057: "Predicate must not be null");
058: }
059: if (closure == null) {
060: throw new IllegalArgumentException(
061: "Closure must not be null");
062: }
063: return new WhileClosure(predicate, closure, doLoop);
064: }
065:
066: /**
067: * Constructor that performs no validation.
068: * Use <code>getInstance</code> if you want that.
069: *
070: * @param predicate the predicate used to evaluate when the loop terminates, not null
071: * @param closure the closure the execute, not null
072: * @param doLoop true to act as a do-while loop, always executing the closure once
073: */
074: public WhileClosure(Predicate predicate, Closure closure,
075: boolean doLoop) {
076: super ();
077: iPredicate = predicate;
078: iClosure = closure;
079: iDoLoop = doLoop;
080: }
081:
082: /**
083: * Executes the closure until the predicate is false.
084: *
085: * @param input the input object
086: */
087: public void execute(Object input) {
088: if (iDoLoop) {
089: iClosure.execute(input);
090: }
091: while (iPredicate.evaluate(input)) {
092: iClosure.execute(input);
093: }
094: }
095:
096: /**
097: * Gets the predicate in use.
098: *
099: * @return the predicate
100: * @since Commons Collections 3.1
101: */
102: public Predicate getPredicate() {
103: return iPredicate;
104: }
105:
106: /**
107: * Gets the closure.
108: *
109: * @return the closure
110: * @since Commons Collections 3.1
111: */
112: public Closure getClosure() {
113: return iClosure;
114: }
115:
116: /**
117: * Is the loop a do-while loop.
118: *
119: * @return true is do-while, false if while
120: * @since Commons Collections 3.1
121: */
122: public boolean isDoLoop() {
123: return iDoLoop;
124: }
125:
126: }
|