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.functor.core.composite;
018
019import java.util.ArrayList;
020import java.util.Iterator;
021import java.util.List;
022
023import org.apache.commons.functor.BinaryProcedure;
024
025/**
026 * A {@link BinaryProcedure BinaryProcedure}
027 * that {@link BinaryProcedure#run runs} an ordered
028 * sequence of {@link BinaryProcedure BinaryProcedures}.
029 * When the sequence is empty, this procedure is does
030 * nothing.
031 *
032 * @param <L> the procedure left argument type.
033 * @param <R> the procedure right argument type.
034 * @version $Revision: 1537602 $ $Date: 2013-10-31 20:53:09 +0100 (Do, 31 Okt 2013) $
035 */
036public class BinarySequence<L, R> implements BinaryProcedure<L, R> {
037    // attributes
038    // ------------------------------------------------------------------------
039    /**
040     * A list where storing all the procedures references.
041     */
042    private final List<BinaryProcedure<? super L, ? super R>> list =
043        new ArrayList<BinaryProcedure<? super L, ? super R>>();
044
045    // constructor
046    // ------------------------------------------------------------------------
047    /**
048     * Create a new BinarySequence.
049     */
050    public BinarySequence() {
051        super();
052    }
053
054    /**
055     * Create a new BinarySequence instance.
056     *
057     * @param procedures to run sequentially
058     */
059    public BinarySequence(BinaryProcedure<? super L, ? super R>... procedures) {
060        this();
061        if (procedures != null) {
062            for (BinaryProcedure<? super L, ? super R> p : procedures) {
063                then(p);
064            }
065        }
066    }
067
068    /**
069     * Create a new BinarySequence instance.
070     *
071     * @param procedures to run sequentially
072     */
073    public BinarySequence(Iterable<BinaryProcedure<? super L, ? super R>> procedures) {
074        this();
075        if (procedures != null) {
076            for (BinaryProcedure<? super L, ? super R> p : procedures) {
077                then(p);
078            }
079        }
080    }
081
082    /**
083     * Fluently add a BinaryProcedure.
084     * @param p BinaryProcedure to add
085     * @return this
086     */
087    public final BinarySequence<L, R> then(BinaryProcedure<? super L, ? super R> p) {
088        list.add(p);
089        return this;
090    }
091
092    // predicate interface
093    // ------------------------------------------------------------------------
094    /**
095     * {@inheritDoc}
096     */
097    public final void run(L left, R right) {
098        for (Iterator<BinaryProcedure<? super L, ? super R>> iter = list.iterator(); iter.hasNext();) {
099            iter.next().run(left, right);
100        }
101    }
102
103    /**
104     * {@inheritDoc}
105     */
106    @Override
107    public final boolean equals(Object obj) {
108        if (obj == this) {
109            return true;
110        }
111        if (!(obj instanceof BinarySequence<?, ?>)) {
112            return false;
113        }
114        BinarySequence<?, ?> that = (BinarySequence<?, ?>) obj;
115        return this.list.equals(that.list);
116    }
117
118    /**
119     * {@inheritDoc}
120     */
121    @Override
122    public int hashCode() {
123        // by construction, list is never null
124        return "BinarySequence".hashCode() ^ list.hashCode();
125    }
126
127    /**
128     * {@inheritDoc}
129     */
130    @Override
131    public String toString() {
132        return "BinarySequence<" + list + ">";
133    }
134
135}