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    
018    package org.apache.commons.beanutils;
019    
020    import org.apache.commons.collections.Predicate;
021    import org.apache.commons.logging.Log;
022    import org.apache.commons.logging.LogFactory;
023    
024    import java.lang.reflect.InvocationTargetException;
025    
026    /**
027     * <p>Predicate implementation that applies the given <code>Predicate</code>
028     * to the result of calling the given property getter.
029     * </p>
030     */
031    public class BeanPredicate implements Predicate {
032       
033        private final Log log = LogFactory.getLog(this.getClass());
034        
035        /** Name of the property whose value will be predicated */
036        private String propertyName;
037        /** <code>Predicate</code> to be applied to the property value */
038        private Predicate predicate;
039    
040        /**
041         * Constructs a <code>BeanPredicate</code> that applies the given
042         * <code>Predicate</code> to the named property value.
043         * @param propertyName the name of the property whose value is to be predicated,
044         * not null
045         * @param predicate the <code>Predicate</code> to be applied,
046         * not null
047         */
048        public BeanPredicate(String propertyName, Predicate predicate) {
049            this.propertyName = propertyName;
050            this.predicate = predicate;
051        }
052    
053        /**
054         * Evaluates the given object by applying the {@link #getPredicate()}
055         * to a property value named by {@link #getPropertyName()}.
056         *
057         * @param object The object being evaluated
058         * @return the result of the predicate evaluation
059         * @throws IllegalArgumentException when the property cannot be evaluated
060         */
061        public boolean evaluate(Object object) {
062           
063            boolean evaluation = false;
064    
065            try {
066                Object propValue = PropertyUtils.getProperty( object, propertyName );
067                evaluation = predicate.evaluate(propValue);
068            } catch (IllegalArgumentException e) {
069                final String errorMsg = "Problem during evaluation.";
070                log.error("ERROR: " + errorMsg, e);
071                throw e;
072            } catch (IllegalAccessException e) {
073                final String errorMsg = "Unable to access the property provided.";
074                log.error(errorMsg, e);
075                throw new IllegalArgumentException(errorMsg);
076            } catch (InvocationTargetException e) {
077                final String errorMsg = "Exception occurred in property's getter";
078                log.error(errorMsg, e);
079                throw new IllegalArgumentException(errorMsg);
080            } catch (NoSuchMethodException e) {
081                final String errorMsg = "Property not found.";
082                log.error(errorMsg, e);
083                throw new IllegalArgumentException(errorMsg);
084            }
085    
086            return evaluation;
087        }
088    
089        /**
090         * Gets the name of the property whose value is to be predicated.
091         * in the evaluation.
092         * @return the property name, not null
093         */ 
094        public String getPropertyName() {
095            return propertyName;
096        }
097    
098        /** 
099         * Sets the name of the property whose value is to be predicated.
100         * @param propertyName the name of the property whose value is to be predicated,
101         * not null
102         */
103        public void setPropertyName(String propertyName) {
104            this.propertyName = propertyName;
105        }
106    
107        /**
108         * Gets the <code>Predicate</code> to be applied to the value of the named property
109         * during {@link #evaluate}.
110         * @return <code>Predicate</code>, not null
111         */
112        public Predicate getPredicate() {
113            return predicate;
114        }
115    
116        /** 
117         * Sets the <code>Predicate</code> to be applied to the value of the named property
118         * during {@link #evaluate(Object)}.
119         * @param predicate <code>Predicate</code>, not null
120         */
121        public void setPredicate(Predicate predicate) {
122            this.predicate = predicate;
123        }
124    
125    }