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.collections4.functors;
018
019import java.io.Serializable;
020import java.util.Objects;
021
022import org.apache.commons.collections4.Predicate;
023import org.apache.commons.collections4.Transformer;
024
025/**
026 * Predicate implementation that transforms the given object before invoking
027 * another {@code Predicate}.
028 *
029 * @since 3.1
030 */
031public final class TransformedPredicate<T> implements PredicateDecorator<T>, Serializable {
032
033    /** Serial version UID */
034    private static final long serialVersionUID = -5596090919668315834L;
035
036    /**
037     * Factory to create the predicate.
038     *
039     * @param <T> the type that the predicate queries
040     * @param transformer  the transformer to call
041     * @param predicate  the predicate to call with the result of the transform
042     * @return the predicate
043     * @throws NullPointerException if the transformer or the predicate is null
044     */
045    public static <T> Predicate<T> transformedPredicate(final Transformer<? super T, ? extends T> transformer,
046                                                        final Predicate<? super T> predicate) {
047        return new TransformedPredicate<>(Objects.requireNonNull(transformer, "transformer"),
048                Objects.requireNonNull(predicate, "predicate"));
049    }
050
051    /** The transformer to call */
052    private final Transformer<? super T, ? extends T> iTransformer;
053
054    /** The predicate to call */
055    private final Predicate<? super T> iPredicate;
056
057    /**
058     * Constructor that performs no validation.
059     * Use {@code transformedPredicate} if you want that.
060     *
061     * @param transformer  the transformer to use
062     * @param predicate  the predicate to decorate
063     */
064    public TransformedPredicate(final Transformer<? super T, ? extends T> transformer,
065                                final Predicate<? super T> predicate) {
066        iTransformer = transformer;
067        iPredicate = predicate;
068    }
069
070    /**
071     * Evaluates the predicate returning the result of the decorated predicate
072     * once the input has been transformed
073     *
074     * @param object  the input object which will be transformed
075     * @return true if decorated predicate returns true
076     */
077    @Override
078    public boolean evaluate(final T object) {
079        final T result = iTransformer.transform(object);
080        return iPredicate.evaluate(result);
081    }
082
083    /**
084     * Gets the predicate being decorated.
085     *
086     * @return the predicate as the only element in an array
087     * @since 3.1
088     */
089    @Override
090    @SuppressWarnings("unchecked")
091    public Predicate<? super T>[] getPredicates() {
092        return new Predicate[] {iPredicate};
093    }
094
095    /**
096     * Gets the transformer in use.
097     *
098     * @return the transformer
099     */
100    public Transformer<? super T, ? extends T> getTransformer() {
101        return iTransformer;
102    }
103
104}