KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > beanutils > BeanPropertyValueEqualsPredicate


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16  
17 package org.apache.commons.beanutils;
18
19 import org.apache.commons.collections.Predicate;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 import java.lang.reflect.InvocationTargetException JavaDoc;
24
25
26 /**
27  * <p><code>Predicate</code> that evaluates a property value against a specified value.</p>
28  * <p>
29  * An implementation of <code>org.apache.commons.collections.Predicate</code> that evaluates a
30  * property value on the object provided against a specified value and returns <code>true</code>
31  * if equal; <code>false</code> otherwise.
32  * The <code>BeanPropertyValueEqualsPredicate</code> constructor takes two parameters which
33  * determine what property will be evaluated on the target object and what its expected value should
34  * be.
35  * <dl>
36  * <dt>
37  * <strong><code><pre>public BeanPropertyValueEqualsPredicate( String propertyName, Object propertyValue )</pre></code></strong>
38  * </dt>
39  * <dd>
40  * Will create a <code>Predicate</code> that will evaluate the target object and return
41  * <code>true</code> if the property specified by <code>propertyName</code> has a value which
42  * is equal to the the value specified by <code>propertyValue</code>. Or return
43  * <code>false</code> otherwise.
44  * </dd>
45  * </dl>
46  * </p>
47  * <p>
48  * <strong>Note:</strong> Property names can be a simple, nested, indexed, or mapped property as defined by
49  * <code>org.apache.commons.beanutils.PropertyUtils</code>. If any object in the property path
50  * specified by <code>propertyName</code> is <code>null</code> then the outcome is based on the
51  * value of the <code>ignoreNull</code> attribute.
52  * </p>
53  * <p>
54  * A typical usage might look like:
55  * <code><pre>
56  * // create the closure
57  * BeanPropertyValueEqualsPredicate predicate =
58  * new BeanPropertyValueEqualsPredicate( "activeEmployee", Boolean.FALSE );
59  *
60  * // filter the Collection
61  * CollectionUtils.filter( peopleCollection, predicate );
62  * </pre></code>
63  * </p>
64  * <p>
65  * This would take a <code>Collection</code> of person objects and filter out any people whose
66  * <code>activeEmployee</code> property is <code>false</code>. Assuming...
67  * <ul>
68  * <li>
69  * The top level object in the <code>peeopleCollection</code> is an object which represents a
70  * person.
71  * </li>
72  * <li>
73  * The person object has a <code>getActiveEmployee()</code> method which returns
74  * the boolean value for the object's <code>activeEmployee</code> property.
75  * </li>
76  * </ul>
77  * </p>
78  * <p>
79  * Another typical usage might look like:
80  * <code><pre>
81  * // create the closure
82  * BeanPropertyValueEqualsPredicate predicate =
83  * new BeanPropertyValueEqualsPredicate( "personId", "456-12-1234" );
84  *
85  * // search the Collection
86  * CollectionUtils.find( peopleCollection, predicate );
87  * </pre><code>
88  * </p>
89  * <p>
90  * This would search a <code>Collection</code> of person objects and return the first object whose
91  * <code>personId</code> property value equals <code>456-12-1234</code>. Assuming...
92  * <ul>
93  * <li>
94  * The top level object in the <code>peeopleCollection</code> is an object which represents a
95  * person.
96  * </li>
97  * <li>
98  * The person object has a <code>getPersonId()</code> method which returns
99  * the value for the object's <code>personId</code> property.
100  * </li>
101  * </ul>
102  * </p>
103  *
104  * @author Norm Deane
105  * @see org.apache.commons.beanutils.PropertyUtils
106  * @see org.apache.commons.collections.Predicate
107  */

108 public class BeanPropertyValueEqualsPredicate implements Predicate {
109    
110     /** For logging. */
111     private final Log log = LogFactory.getLog(this.getClass());
112
113     /**
114      * The name of the property which will be evaluated when this <code>Predicate</code> is executed.
115      */

116     private String JavaDoc propertyName;
117
118     /**
119      * The value that the property specified by <code>propertyName</code>
120      * will be compared to when this <code>Predicate</code> executes.
121      */

122     private Object JavaDoc propertyValue;
123
124     /**
125      * <p>Should <code>null</code> objects in the property path be ignored?</p>
126      * <p>
127      * Determines whether <code>null</code> objects in the property path will genenerate an
128      * <code>IllegalArgumentException</code> or not. If set to <code>true</code> then if any objects
129      * in the property path evaluate to <code>null</code> then the
130      * <code>IllegalArgumentException</code> throw by <code>PropertyUtils</code> will be logged but
131      * not rethrown and <code>false</code> will be returned. If set to <code>false</code> then if
132      * any objects in the property path evaluate to <code>null</code> then the
133      * <code>IllegalArgumentException</code> throw by <code>PropertyUtils</code> will be logged and
134      * rethrown.
135      * </p>
136      */

137     private boolean ignoreNull;
138
139     /**
140      * Constructor which takes the name of the property, its expected value to be used in evaluation,
141      * and assumes <code>ignoreNull</code> to be <code>false</code>.
142      *
143      * @param propertyName The name of the property that will be evaluated against the expected value.
144      * @param propertyValue The value to use in object evaluation.
145      * @throws IllegalArgumentException If the property name provided is null or empty.
146      */

147     public BeanPropertyValueEqualsPredicate(String JavaDoc propertyName, Object JavaDoc propertyValue) {
148         this(propertyName, propertyValue, false);
149     }
150
151     /**
152      * Constructor which takes the name of the property, its expected value
153      * to be used in evaluation, and a boolean which determines whether <code>null</code> objects in
154      * the property path will genenerate an <code>IllegalArgumentException</code> or not.
155      *
156      * @param propertyName The name of the property that will be evaluated against the expected value.
157      * @param propertyValue The value to use in object evaluation.
158      * @param ignoreNull Determines whether <code>null</code> objects in the property path will
159      * genenerate an <code>IllegalArgumentException</code> or not.
160      * @throws IllegalArgumentException If the property name provided is null or empty.
161      */

162     public BeanPropertyValueEqualsPredicate(String JavaDoc propertyName, Object JavaDoc propertyValue, boolean ignoreNull) {
163         super();
164
165         if ((propertyName != null) && (propertyName.length() > 0)) {
166             this.propertyName = propertyName;
167             this.propertyValue = propertyValue;
168             this.ignoreNull = ignoreNull;
169         } else {
170             throw new IllegalArgumentException JavaDoc("propertyName cannot be null or empty");
171         }
172     }
173
174     /**
175      * Evaulates the object provided against the criteria specified when this
176      * <code>BeanPropertyValueEqualsPredicate</code> was constructed. Equality is based on
177      * either reference or logical equality as defined by the property object's equals method. If
178      * any object in the property path leading up to the target property is <code>null</code> then
179      * the outcome will be based on the value of the <code>ignoreNull</code> attribute. By default,
180      * <code>ignoreNull</code> is <code>false</code> and would result in an
181      * <code>IllegalArgumentException</code> if an object in the property path leading up to the
182      * target property is <code>null</code>.
183      *
184      * @param object The object to be evaluated.
185      * @return True if the object provided meets all the criteria for this <code>Predicate</code>;
186      * false otherwise.
187      * @throws IllegalArgumentException If an IllegalAccessException, InvocationTargetException, or
188      * NoSuchMethodException is thrown when trying to access the property specified on the object
189      * provided. Or if an object in the property path provided is <code>null</code> and
190      * <code>ignoreNull</code> is set to <code>false</code>.
191      */

192     public boolean evaluate(Object JavaDoc object) {
193        
194         boolean evaluation = false;
195
196         try {
197             evaluation = evaluateValue(propertyValue,
198                     PropertyUtils.getProperty(object, propertyName));
199         } catch (IllegalArgumentException JavaDoc e) {
200             final String JavaDoc errorMsg = "Problem during evaluation. Null value encountered in property path...";
201
202             if (ignoreNull) {
203                 log.warn("WARNING: " + errorMsg, e);
204             } else {
205                 log.error("ERROR: " + errorMsg, e);
206                 throw e;
207             }
208         } catch (IllegalAccessException JavaDoc e) {
209             final String JavaDoc errorMsg = "Unable to access the property provided.";
210             log.error(errorMsg, e);
211             throw new IllegalArgumentException JavaDoc(errorMsg);
212         } catch (InvocationTargetException JavaDoc e) {
213             final String JavaDoc errorMsg = "Exception occurred in property's getter";
214             log.error(errorMsg, e);
215             throw new IllegalArgumentException JavaDoc(errorMsg);
216         } catch (NoSuchMethodException JavaDoc e) {
217             final String JavaDoc errorMsg = "Property not found.";
218             log.error(errorMsg, e);
219             throw new IllegalArgumentException JavaDoc(errorMsg);
220         }
221
222         return evaluation;
223     }
224
225     /**
226      * Utility method which evaluates whether the actual property value equals the expected property
227      * value.
228      *
229      * @param expected The expected value.
230      * @param actual The actual value.
231      * @return True if they are equal; false otherwise.
232      */

233     private boolean evaluateValue(Object JavaDoc expected, Object JavaDoc actual) {
234         return (expected == actual) || ((expected != null) && expected.equals(actual));
235     }
236
237     /**
238      * Returns the name of the property which will be evaluated when this <code>Predicate</code> is
239      * executed.
240      *
241      * @return The name of the property which will be evaluated when this <code>Predicate</code> is
242      * executed.
243      */

244     public String JavaDoc getPropertyName() {
245         return propertyName;
246     }
247
248     /**
249      * Returns the value that the property specified by <code>propertyName</code> will be compared to
250      * when this <code>Predicate</code> executes.
251      *
252      * @return The value that the property specified by <code>propertyName</code> will be compared to
253      * when this <code>Predicate</code> executes.
254      */

255     public Object JavaDoc getPropertyValue() {
256         return propertyValue;
257     }
258
259     /**
260      * Returns the flag which determines whether <code>null</code> objects in the property path will
261      * genenerate an <code>IllegalArgumentException</code> or not. If set to <code>true</code> then
262      * if any objects in the property path evaluate to <code>null</code> then the
263      * <code>IllegalArgumentException</code> throw by <code>PropertyUtils</code> will be logged but
264      * not rethrown and <code>false</code> will be returned. If set to <code>false</code> then if
265      * any objects in the property path evaluate to <code>null</code> then the
266      * <code>IllegalArgumentException</code> throw by <code>PropertyUtils</code> will be logged and
267      * rethrown.
268      *
269      * @return The flag which determines whether <code>null</code> objects in the property path will
270      * genenerate an <code>IllegalArgumentException</code> or not.
271      */

272     public boolean isIgnoreNull() {
273         return ignoreNull;
274     }
275 }
276
Popular Tags