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.io.Serializable; 020 021import org.apache.commons.functor.Function; 022import org.apache.commons.functor.UnaryFunction; 023import org.apache.commons.lang3.Validate; 024 025/** 026 * A Function whose result is then run through a UnaryFunction. 027 * 028 * @param <T> the returned value type. 029 * @version $Revision: 1365329 $ $Date: 2012-07-24 18:34:23 -0400 (Tue, 24 Jul 2012) $ 030 */ 031public class TransformedFunction<T> implements Function<T>, Serializable { 032 /** 033 * serialVersionUID declaration. 034 */ 035 private static final long serialVersionUID = 1201423110871342081L; 036 037 /** 038 * Type-remembering helper. 039 * 040 * @param <X> the adapted function argument type 041 */ 042 private static final class Helper<X, T> implements Function<T>, Serializable { 043 /** 044 * serialVersionUID declaration. 045 */ 046 private static final long serialVersionUID = -7177784125292465809L; 047 /** 048 * The preceding function. 049 */ 050 private Function<? extends X> preceding; 051 /** 052 * The following function. 053 */ 054 private UnaryFunction<? super X, ? extends T> following; 055 056 /** 057 * Create a new Helper. 058 * @param preceding Function 059 * @param following UnaryFunction 060 */ 061 private Helper(Function<? extends X> preceding, UnaryFunction<? super X, ? extends T> following) { 062 this.preceding = Validate.notNull(preceding, "Function argument was null"); 063 this.following = Validate.notNull(following, "UnaryFunction argument was null"); 064 } 065 066 /** 067 * {@inheritDoc} 068 */ 069 public T evaluate() { 070 return following.evaluate(preceding.evaluate()); 071 } 072 } 073 074 /** 075 * The adapted helper. 076 */ 077 private final Helper<?, T> helper; 078 079 /** 080 * Create a new TransformedFunction. 081 * @param <X> the preceding function argument type. 082 * @param preceding Function 083 * @param following UnaryFunction 084 */ 085 public <X> TransformedFunction(Function<? extends X> preceding, 086 UnaryFunction<? super X, ? extends T> following) { 087 this.helper = new Helper<X, T>(preceding, following); 088 } 089 090 /** 091 * {@inheritDoc} 092 */ 093 public final T evaluate() { 094 return helper.evaluate(); 095 } 096 097 /** 098 * {@inheritDoc} 099 */ 100 @Override 101 public final boolean equals(Object obj) { 102 return obj == this || obj instanceof TransformedFunction<?> && equals((TransformedFunction<?>) obj); 103 } 104 105 /** 106 * Learn whether another TransformedFunction is equal to <code>this</code>. 107 * @param that instance to test 108 * @return whether equal 109 */ 110 public final boolean equals(TransformedFunction<?> that) { 111 return that != null && that.helper.preceding.equals(this.helper.preceding) 112 && that.helper.following.equals(this.helper.following); 113 } 114 115 /** 116 * {@inheritDoc} 117 */ 118 @Override 119 public int hashCode() { 120 int result = "TransformedFunction".hashCode(); 121 result <<= 2; 122 result |= helper.following.hashCode(); 123 result <<= 2; 124 result |= helper.preceding.hashCode(); 125 return result; 126 } 127 128 /** 129 * {@inheritDoc} 130 */ 131 @Override 132 public String toString() { 133 return "TransformedFunction<" + helper.preceding + "; " + helper.following + ">"; 134 } 135}