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.functor.generator;
018    
019    import org.apache.commons.functor.UnaryPredicate;
020    import org.apache.commons.functor.UnaryProcedure;
021    
022    /**
023     * Wrap another {@link Generator} such that {@link #run(UnaryProcedure)} terminates once
024     * a condition has been satisfied (test after).
025     *
026     * @version $Revision: 1156796 $ $Date: 2011-08-11 22:09:21 +0200 (Thu, 11 Aug 2011) $
027     */
028    public class GenerateUntil<E> extends BaseGenerator<E> {
029        private final UnaryPredicate<? super E> test;
030    
031        /**
032         * Create a new GenerateUntil.
033         * @param wrapped {@link Generator}
034         * @param test {@link UnaryPredicate}
035         */
036        public GenerateUntil(Generator<? extends E> wrapped, UnaryPredicate<? super E> test) {
037            super(wrapped);
038            if (wrapped == null) {
039                throw new IllegalArgumentException("Generator argument was null");
040            }
041            if (test == null) {
042                throw new IllegalArgumentException("UnaryPredicate argument was null");
043            }
044            this.test = test;
045        }
046    
047        /**
048         * {@inheritDoc}
049         */
050        public void run(final UnaryProcedure<? super E> proc) {
051            getWrappedGenerator().run(new UnaryProcedure<E>() {
052                public void run(E obj) {
053                    proc.run(obj);
054                    if (test.test(obj)) {
055                        getWrappedGenerator().stop();
056                    }
057                }
058            });
059        }
060    
061        /**
062         * {@inheritDoc}
063         */
064        @SuppressWarnings("unchecked")
065        @Override
066        protected Generator<? extends E> getWrappedGenerator() {
067            return (Generator<? extends E>) super.getWrappedGenerator();
068        }
069    
070        /**
071         * {@inheritDoc}
072         */
073        public boolean equals(Object obj) {
074            if (obj == this) {
075                return true;
076            }
077            if (!(obj instanceof GenerateUntil<?>)) {
078                return false;
079            }
080            GenerateUntil<?> other = (GenerateUntil<?>) obj;
081            return other.getWrappedGenerator().equals(getWrappedGenerator()) && other.test.equals(test);
082        }
083    
084        /**
085         * {@inheritDoc}
086         */
087        public int hashCode() {
088            int result = "GenerateUntil".hashCode();
089            result <<= 2;
090            Generator<?> gen = getWrappedGenerator();
091            result ^= gen == null ? 0 : gen.hashCode();
092            result <<= 2;
093            result ^= test == null ? 0 : test.hashCode();
094            return result;
095        }
096    }