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.core.composite;
018    
019    import java.io.Serializable;
020    
021    import org.apache.commons.functor.Function;
022    import org.apache.commons.functor.Procedure;
023    import org.apache.commons.functor.UnaryProcedure;
024    
025    /**
026     * A Procedure composed of a Function whose result is then run through a UnaryProcedure.
027     * @version $Revision: 1171154 $ $Date: 2011-09-15 17:58:38 +0200 (Thu, 15 Sep 2011) $
028     * @author Matt Benson
029     */
030    public class TransformedProcedure implements Procedure, Serializable {
031        /**
032         * serialVersionUID declaration.
033         */
034        private static final long serialVersionUID = -4111958123789033410L;
035    
036        /** Base hash integer used to shift hash */
037        private static final int HASH_SHIFT = 2;
038    
039        /**
040         * Type-remembering helper
041         * @param <X>
042         */
043        private static final class Helper<X> implements Procedure, Serializable {
044            /**
045             * serialVersionUID declaration.
046             */
047            private static final long serialVersionUID = -4093503167446891318L;
048            private Function<? extends X> function;
049            private UnaryProcedure<? super X> procedure;
050    
051            /**
052             * Create a new Helper.
053             * @param function Function
054             * @param procedure UnaryFunction
055             */
056            private Helper(Function<? extends X> function, UnaryProcedure<? super X> procedure) {
057                this.function = function;
058                this.procedure = procedure;
059            }
060    
061            /**
062             * {@inheritDoc}
063             */
064            public void run() {
065                procedure.run(function.evaluate());
066            }
067        }
068    
069        private final Helper<?> helper;
070    
071        /**
072         * Create a new TransformedProcedure.
073         * @param <X>
074         * @param function Function
075         * @param procedure UnaryProcedure
076         */
077        public <X> TransformedProcedure(Function<? extends X> function, UnaryProcedure<? super X> procedure) {
078            this.helper = new Helper<X>(function, procedure);
079        }
080    
081        /**
082         * {@inheritDoc}
083         */
084        public final void run() {
085            helper.run();
086        }
087    
088        /**
089         * {@inheritDoc}
090         */
091        @Override
092        public final boolean equals(Object obj) {
093            return obj == this || obj instanceof TransformedProcedure
094                    && equals((TransformedProcedure) obj);
095        }
096    
097        /**
098         * Learn whether another TransformedProcedure is equal to <code>this</code>.
099         * @param that instance to test
100         * @return whether equal
101         */
102        public final boolean equals(TransformedProcedure that) {
103            return that != null && that.helper.function.equals(this.helper.function)
104                    && that.helper.procedure.equals(this.helper.procedure);
105        }
106    
107        /**
108         * {@inheritDoc}
109         */
110        @Override
111        public int hashCode() {
112            int result = "TransformedProcedure".hashCode();
113            result <<= HASH_SHIFT;
114            result |= helper.procedure.hashCode();
115            result <<= HASH_SHIFT;
116            result |= helper.function.hashCode();
117            return result;
118        }
119    
120        /**
121         * {@inheritDoc}
122         */
123        @Override
124        public String toString() {
125            return "TransformedProcedure<" + helper.function + "; " + helper.procedure + ">";
126        }
127    }