Coverage Report - org.apache.commons.functor.core.composite.CompositeUnaryFunction
 
Classes in this File Line Coverage Branch Coverage Complexity
CompositeUnaryFunction
93%
15/16
85%
12/14
1.714
CompositeUnaryFunction$Helper
100%
14/14
80%
8/10
1.714
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.functor.core.composite;
 18  
 
 19  
 import java.io.Serializable;
 20  
 
 21  
 import org.apache.commons.functor.UnaryFunction;
 22  
 
 23  
 /**
 24  
  * A {@link UnaryFunction UnaryFunction}
 25  
  * representing the composition of
 26  
  * {@link UnaryFunction UnaryFunctions},
 27  
  * "chaining" the output of one to the input
 28  
  * of another.  For example,
 29  
  * <pre>new CompositeUnaryFunction(f).of(g)</pre>
 30  
  * {@link #evaluate evaluates} to
 31  
  * <code>f.evaluate(g.evaluate(obj))</code>, and
 32  
  * <pre>new CompositeUnaryFunction(f).of(g).of(h)</pre>
 33  
  * {@link #evaluate evaluates} to
 34  
  * <code>f.evaluate(g.evaluate(h.evaluate(obj)))</code>.
 35  
  * <p>
 36  
  * When the collection is empty, this function is
 37  
  * an identity function.
 38  
  * </p>
 39  
  * <p>
 40  
  * Note that although this class implements
 41  
  * {@link Serializable}, a given instance will
 42  
  * only be truly <code>Serializable</code> if all the
 43  
  * underlying functors are.  Attempts to serialize
 44  
  * an instance whose delegates are not all
 45  
  * <code>Serializable</code> will result in an exception.
 46  
  * </p>
 47  
  * @version $Revision: 1171157 $ $Date: 2011-09-15 18:04:31 +0200 (Thu, 15 Sep 2011) $
 48  
  * @author Rodney Waldhoff
 49  
  * @author Matt Benson
 50  
  */
 51  
 public class CompositeUnaryFunction<A, T> implements UnaryFunction<A, T>, Serializable {
 52  
 
 53  
     /**
 54  
      * serialVersionUID declaration.
 55  
      */
 56  
     private static final long serialVersionUID = 4945193629275757281L;
 57  
 
 58  
     /** Base hash integer used to shift hash */
 59  
     private static final int HASH_SHIFT = 4;
 60  
 
 61  
     /**
 62  
      * Encapsulates a double function evaluation.
 63  
      * @param <A> argument type
 64  
      * @param <X> intermediate type
 65  
      * @param <T> return type
 66  
      */
 67  
     private static class Helper<X, A, T> implements UnaryFunction<A, T>, Serializable {
 68  
         /**
 69  
          * serialVersionUID declaration.
 70  
          */
 71  
         private static final long serialVersionUID = 8167255331321876718L;
 72  
         private UnaryFunction<? super X, ? extends T> following;
 73  
         private UnaryFunction<? super A, ? extends X> preceding;
 74  
 
 75  
         /**
 76  
          * Create a new Helper.
 77  
          * @param following UnaryFunction<X, Y>
 78  
          * @param preceding UnaryFunction<Y, Z>
 79  
          */
 80  
         public Helper(UnaryFunction<? super X, ? extends T> following,
 81  148
                 UnaryFunction<? super A, ? extends X> preceding) {
 82  148
             this.following = following;
 83  148
             this.preceding = preceding;
 84  148
         }
 85  
 
 86  
         /**
 87  
          * {@inheritDoc}
 88  
          */
 89  
         public T evaluate(A obj) {
 90  914
             return following.evaluate(preceding.evaluate(obj));
 91  
         }
 92  
 
 93  
         /**
 94  
          * {@inheritDoc}
 95  
          */
 96  
         @Override
 97  
         public boolean equals(Object obj) {
 98  300
             return obj == this || obj instanceof Helper<?, ?, ?> && equals((Helper<?, ?, ?>) obj);
 99  
         }
 100  
 
 101  
         private boolean equals(Helper<?, ?, ?> helper) {
 102  282
             return helper.following.equals(following) && helper.preceding.equals(preceding);
 103  
         }
 104  
 
 105  
         /**
 106  
          * {@inheritDoc}
 107  
          */
 108  
         @Override
 109  
         public int hashCode() {
 110  350
             int result = "CompositeUnaryFunction$Helper".hashCode();
 111  350
             result <<= 2;
 112  350
             result |= following.hashCode();
 113  350
             result <<= 2;
 114  350
             result |= preceding.hashCode();
 115  350
             return result;
 116  
         }
 117  
 
 118  
         /**
 119  
          * {@inheritDoc}
 120  
          */
 121  
         @Override
 122  
         public String toString() {
 123  342
             return following.toString() + " of " + preceding.toString();
 124  
         }
 125  
     }
 126  
 
 127  
     private final UnaryFunction<? super A, ? extends T> function;
 128  
 
 129  
     /**
 130  
      * Create a new CompositeUnaryFunction.
 131  
      * @param function UnaryFunction to call
 132  
      */
 133  84
     public CompositeUnaryFunction(UnaryFunction<? super A, ? extends T> function) {
 134  84
         if (function == null) {
 135  0
             throw new IllegalArgumentException("function must not be null");
 136  
         }
 137  84
         this.function = function;
 138  84
     }
 139  
 
 140  
     private <X> CompositeUnaryFunction(UnaryFunction<? super X, ? extends T> following,
 141  148
             UnaryFunction<? super A, ? extends X> preceding) {
 142  148
         this.function = new Helper<X, A, T>(following, preceding);
 143  148
     }
 144  
 
 145  
     /**
 146  
      * {@inheritDoc}
 147  
      */
 148  
     public final T evaluate(A obj) {
 149  760
         return function.evaluate(obj);
 150  
     }
 151  
 
 152  
     /**
 153  
      * Fluently obtain a CompositeUnaryFunction that is "this function" applied to the specified preceding function.
 154  
      * @param <P> argument type of the resulting function.
 155  
      * @param preceding UnaryFunction
 156  
      * @return CompositeUnaryFunction<P, T>
 157  
      */
 158  
     public final <P> CompositeUnaryFunction<P, T> of(UnaryFunction<? super P, ? extends A> preceding) {
 159  150
         if (preceding == null) {
 160  2
             throw new IllegalArgumentException("preceding function was null");
 161  
         }
 162  148
         return new CompositeUnaryFunction<P, T>(function, preceding);
 163  
     }
 164  
 
 165  
     /**
 166  
      * {@inheritDoc}
 167  
      */
 168  
     public final boolean equals(Object that) {
 169  42
         return that == this
 170  
                 || (that instanceof CompositeUnaryFunction<?, ?> && equals((CompositeUnaryFunction<?, ?>) that));
 171  
     }
 172  
 
 173  
     /**
 174  
      * Learn whether another CompositeUnaryFunction is equal to this.
 175  
      * @param that CompositeUnaryFunction to test
 176  
      * @return boolean
 177  
      */
 178  
     public final boolean equals(CompositeUnaryFunction<?, ?> that) {
 179  
         // by construction, list is never null
 180  98
         return null != that && function.equals(that.function);
 181  
     }
 182  
 
 183  
     /**
 184  
      * {@inheritDoc}
 185  
      */
 186  
     public int hashCode() {
 187  
         // by construction, list is never null
 188  126
         return ("CompositeUnaryFunction".hashCode() << HASH_SHIFT) ^ function.hashCode();
 189  
     }
 190  
 
 191  
     /**
 192  
      * {@inheritDoc}
 193  
      */
 194  
     public String toString() {
 195  102
         return "CompositeUnaryFunction<" + function + ">";
 196  
     }
 197  
 
 198  
 }