001: // ============================================================================
002: // $Id: ComposeUnary.java,v 1.9 2006/01/08 00:52:25 davidahall Exp $
003: // Copyright (c) 2002-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.adaptor;
034:
035: import net.sf.jga.fn.BinaryFunctor;
036: import net.sf.jga.fn.UnaryFunctor;
037:
038: /**
039: * Unary Functor that passes the results of two Unary Functors as the arguments
040: * to a Binary Functor. This allows for the construction of compound functors
041: * from the primitives found in the arithmetic, logical, property, and
042: * comparison packages.
043: * <p>
044: * For example: LogicalAnd is of limited utility since it takes only Boolean
045: * arguments. To use LogicalAnd for something a little more interesting
046: * (eg, is the given integer between 1 and 10), combine LogicalAnd with
047: * GreaterEqual and LessEqual using Binary Compose and Bind1st as follows:
048: * <pre>
049: * new ComposeUnary<Integer,Boolean,Boolean,Boolean> (
050: * new Bind1st<Integer,Integer,Boolean> (1, new LessEqual<Integer>()),
051: * new Bind1st<Integer,Integer,Boolean> (10, new GreaterEqual<Integer>()),
052: * new LogicalAnd());
053: * </pre>
054: * While it may not be the most readable construction in the world, it does
055: * become easier over time.
056: * <p>
057: * Copyright © 2002-2005 David A. Hall
058: *
059: * @author <a href="mailto:davidahall@users.sourceforge.net">David A. Hall</a>
060: **/
061:
062: public class ComposeUnary<T, F1, F2, R> extends UnaryFunctor<T, R> {
063:
064: static final long serialVersionUID = -836030733262754108L;
065:
066: // the first of two inner functors
067: private UnaryFunctor<T, F1> _f;
068:
069: // the second of two inner functors
070: private UnaryFunctor<T, F2> _g;
071:
072: // the outer functor
073: private BinaryFunctor<F1, F2, R> _h;
074:
075: /**
076: * Builds a ComposeUnary functor, given two inner functors <b>f</b> and
077: * <b>g</b>, and outer functor <b>h</b>.
078: * @throws IllegalArgumentException if any of the functors is missing
079: */
080: public ComposeUnary(UnaryFunctor<T, F1> f, UnaryFunctor<T, F2> g,
081: BinaryFunctor<F1, F2, R> h) {
082: if (f == null || g == null || h == null) {
083: throw new IllegalArgumentException(
084: "Three functors are required");
085: }
086:
087: _f = f;
088: _g = g;
089: _h = h;
090: }
091:
092: /**
093: * Returns the first of two inner functors
094: * @return the first of two inner functors
095: */
096: public UnaryFunctor<T, F1> getFirstInnerFunctor() {
097: return _f;
098: }
099:
100: /**
101: * Returns the second of two inner functors
102: * @return the second of two inner functors
103: */
104: public UnaryFunctor<T, F2> getSecondInnerFunctor() {
105: return _g;
106: }
107:
108: /**
109: * Returns the outer functor
110: * @return the outer functor
111: */
112: public BinaryFunctor<F1, F2, R> getOuterFunctor() {
113: return _h;
114: }
115:
116: // UnaryFunctor interface
117:
118: /**
119: * Given argument <b>x</b>, passes x to both inner functors, and passes the
120: * results of those functors to the outer functor.
121: *
122: * @return h(f(x), g(x))
123: */
124: public R fn(T x) {
125: return _h.fn(_f.fn(x), _g.fn(x));
126: }
127:
128: /**
129: * Calls the Visitor's <code>visit(ComposeUnary)</code> method, if it
130: * implements the nested Visitor interface.
131: */
132: public void accept(net.sf.jga.fn.Visitor v) {
133: if (v instanceof ComposeUnary.Visitor)
134: ((ComposeUnary.Visitor) v).visit(this );
135: else
136: v.visit(this );
137: }
138:
139: // Object overrides
140:
141: public String toString() {
142: return _h + ".compose(" + _f + "," + _g + ")";
143: }
144:
145: // Acyclic Visitor
146:
147: /**
148: * Interface for classes that may interpret a <b>ComposeUnary</b> functor.
149: */
150: public interface Visitor extends net.sf.jga.fn.Visitor {
151: public void visit(ComposeUnary host);
152: }
153: }
|