001: // ============================================================================
002: // $Id: Any.java,v 1.18 2006/01/08 00:52:25 davidahall Exp $
003: // Copyright (c) 2003-2005 David A. Hall
004: // ============================================================================
005: // The contents of this file are subject to the Common Development and
006: // Distribution License (CDDL), Version 1.0 (the License); you may not use this
007: // file except in compliance with the License. You should have received a copy
008: // of the the License along with this file: if not, a copy of the License is
009: // available from Sun Microsystems, Inc.
010: //
011: // http://www.sun.com/cddl/cddl.html
012: //
013: // From time to time, the license steward (initially Sun Microsystems, Inc.) may
014: // publish revised and/or new versions of the License. You may not use,
015: // distribute, or otherwise make this file available under subsequent versions
016: // of the License.
017: //
018: // Alternatively, the contents of this file may be used under the terms of the
019: // GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
020: // case the provisions of the LGPL are applicable instead of those above. If you
021: // wish to allow use of your version of this file only under the terms of the
022: // LGPL, and not to allow others to use your version of this file under the
023: // terms of the CDDL, indicate your decision by deleting the provisions above
024: // and replace them with the notice and other provisions required by the LGPL.
025: // If you do not delete the provisions above, a recipient may use your version
026: // of this file under the terms of either the CDDL or the LGPL.
027: //
028: // This library is distributed in the hope that it will be useful,
029: // but WITHOUT ANY WARRANTY; without even the implied warranty of
030: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
031: // ============================================================================
032:
033: package net.sf.jga.fn.logical;
034:
035: import java.util.Collection;
036: import java.util.Iterator;
037: import java.util.ArrayList;
038: import net.sf.jga.fn.UnaryFunctor;
039: import net.sf.jga.fn.UnaryPredicate;
040:
041: /**
042: * Unary Predicate that returns true when one of 0 or more branch predicates
043: * returns true. When the collection of branch predicates is empty, an Any
044: * predicate will return false (somewhat arbitrarily). This predicate will
045: * short circuit: once one of the branches returns true, none of the
046: * subsequent branches will be evaluated.
047: * <p>
048: * The order of evaluation is dependant on the type of collection used: when
049: * using the default constructor, the collection used is a list, and branch
050: * predicates will be evaluated in the order given.
051: * <p>
052: * Copyright © 2003-2005 David A. Hall
053: *
054: * @author <a href="mailto:davidahall@users.sourceforge.net">David A. Hall</a>
055: **/
056:
057: public class Any<T> extends UnaryPredicate<T> {
058:
059: static final long serialVersionUID = -3665390675036353724L;
060:
061: private Collection<UnaryFunctor<T, Boolean>> _branches;
062:
063: /**
064: * Builds the Any predicate with an empty default collection of branch
065: * predicates. The default collection is a list, and branches will be
066: * evaluated in the order they are added.
067: */
068: public Any() {
069: _branches = new ArrayList<UnaryFunctor<T, Boolean>>();
070: }
071:
072: /**
073: * Builds the Any predicate with the given collection of branch predicates.
074: * More predicates may be added to the collection after construction. The
075: * order of evaluation of the branch predicates is determined by the
076: * collection in use.
077: */
078: public Any(Collection<UnaryFunctor<T, Boolean>> branches) {
079: _branches = (branches != null) ? branches
080: : new ArrayList<UnaryFunctor<T, Boolean>>();
081: }
082:
083: /**
084: * Returns an Iterator over the branch predicates.
085: * @return an Iterator over the branch predicates
086: */
087: public Iterator<UnaryFunctor<T, Boolean>> branches() {
088: return _branches.iterator();
089: }
090:
091: // UnaryPredicate interface
092:
093: /**
094: * Given arguments <b>x</b>, returns true if at least one branch predicate
095: * returns true when given x. Returns false when there are no branch
096: * predicates.
097: *
098: * @return true if one branch predicates return true, false otherwise
099: */
100: public Boolean fn(T x) {
101: for (UnaryFunctor<T, Boolean> pred : _branches) {
102: if (pred.fn(x))
103: return true;
104: }
105:
106: return false;
107: }
108:
109: /**
110: * Calls the Visitor's <code>visit(Any)</code> method, if it
111: * implements the nested Visitor interface.
112: */
113: public void accept(net.sf.jga.fn.Visitor v) {
114: if (v instanceof Any.Visitor)
115: ((Any.Visitor) v).visit(this );
116: else
117: v.visit(this );
118: }
119:
120: // Object overrides
121:
122: public String toString() {
123: StringBuffer buf = new StringBuffer("Any(");
124: String sep = "";
125: for (UnaryFunctor<T, Boolean> pred : _branches) {
126: buf.append(sep).append(pred);
127: sep = ",";
128: }
129: buf.append(")");
130: return buf.toString();
131: }
132:
133: // AcyclicVisitor
134:
135: /**
136: * Interface for classes that may interpret an <b>Any</b> predicate.
137: */
138: public interface Visitor extends net.sf.jga.fn.Visitor {
139: public void visit(Any host);
140: }
141: }
|