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.
025     *
026     * @version $Revision: 1156801 $ $Date: 2011-08-11 22:12:44 +0200 (Thu, 11 Aug 2011) $
027     */
028    public class UntilGenerate<E> extends BaseGenerator<E> {
029        private final UnaryPredicate<? super E> test;
030    
031        /**
032         * Create a new UntilGenerate.
033         * @param wrapped {@link Generator}
034         * @param test {@link UnaryPredicate}
035         */
036        public UntilGenerate(UnaryPredicate<? super E> test, Generator<? extends E> wrapped) {
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                    if (test.test(obj)) {
054                        getWrappedGenerator().stop();
055                    } else {
056                        proc.run(obj);
057                    }
058                }
059            });
060        }
061    
062        /**
063         * {@inheritDoc}
064         */
065        @SuppressWarnings("unchecked")
066        @Override
067        protected Generator<? extends E> getWrappedGenerator() {
068            return (Generator<? extends E>) super.getWrappedGenerator();
069        }
070    
071        /**
072         * {@inheritDoc}
073         */
074        public boolean equals(Object obj) {
075            if (obj == this) {
076                return true;
077            }
078            if (!(obj instanceof UntilGenerate<?>)) {
079                return false;
080            }
081            UntilGenerate<?> other = (UntilGenerate<?>) obj;
082            return other.getWrappedGenerator().equals(getWrappedGenerator()) && other.test.equals(test);
083        }
084    
085        /**
086         * {@inheritDoc}
087         */
088        public int hashCode() {
089            int result = "UntilGenerate".hashCode();
090            result <<= 2;
091            Generator<?> gen = getWrappedGenerator();
092            result ^= gen == null ? 0 : gen.hashCode();
093            result <<= 2;
094            result ^= test == null ? 0 : test.hashCode();
095            return result;
096        }
097    }