Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/commons/beanutils/BeanToPropertyValueTransformer.java


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.Transformer;
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  
23  import java.lang.reflect.InvocationTargetException;
24  
25  
26  /**
27   * <p><code>Transformer</code> that outputs a property value.</p>
28   *
29   * <p>An implementation of <code>org.apache.commons.collections.Transformer</code> that transforms
30   * the object provided by returning the value of a specified property of the object.  The
31   * constructor for <code>BeanToPropertyValueTransformer</code> requires the name of the property
32   * that will be used in the transformation.  The property can be a simple, nested, indexed, or
33   * mapped property as defined by <code>org.apache.commons.beanutils.PropertyUtils</code>. If any
34   * object in the property path specified by <code>propertyName</code> is <code>null</code> then the
35   * outcome is based on the value of the <code>ignoreNull</code> attribute.
36   * </p>
37   *
38   * <p>
39   * A typical usage might look like:
40   * <code><pre>
41   * // create the transformer
42   * BeanToPropertyValueTransformer transformer = new BeanToPropertyValueTransformer( "person.address.city" );
43   *
44   * // transform the Collection
45   * Collection peoplesCities = CollectionUtils.collect( peopleCollection, transformer );
46   * </pre></code>
47   * </p>
48   *
49   * <p>
50   * This would take a <code>Collection</code> of person objects and return a <code>Collection</code>
51   * of objects which represents the cities in which each person lived. Assuming...
52   * <ul>
53   *    <li>
54   *       The top level object in the <code>peeopleCollection</code> is an object which represents a
55   *       person.
56   *    </li>
57   *    <li>
58   *       The person object has a <code>getAddress()</code> method which returns an object which
59   *       represents a person's address.
60   *    </li>
61   *    <li>
62   *       The address object has a <code>getCity()</code> method which returns an object which
63   *       represents the city in which a person lives.
64   *    </li>
65   * </ul>
66   *
67   * @author Norm Deane
68   * @see org.apache.commons.beanutils.PropertyUtils
69   * @see org.apache.commons.collections.Transformer
70   */
71  public class BeanToPropertyValueTransformer implements Transformer {
72     
73      /** For logging. */
74      private final Log log = LogFactory.getLog(this.getClass());
75  
76      /** The name of the property that will be used in the transformation of the object. */
77      private String propertyName;
78  
79      /**
80       * <p>Should null objects on the property path throw an <code>IllegalArgumentException</code>?</p>
81       * <p>
82       * Determines whether <code>null</code> objects in the property path will genenerate an
83       * <code>IllegalArgumentException</code> or not. If set to <code>true</code> then if any objects
84       * in the property path evaluate to <code>null</code> then the
85       * <code>IllegalArgumentException</code> throw by <code>PropertyUtils</code> will be logged but
86       * not rethrown and <code>null</code> will be returned.  If set to <code>false</code> then if any
87       * objects in the property path evaluate to <code>null</code> then the
88       * <code>IllegalArgumentException</code> throw by <code>PropertyUtils</code> will be logged and
89       * rethrown.
90       * </p>
91       */
92      private boolean ignoreNull;
93  
94      /**
95       * Constructs a Transformer which does not ignore nulls.
96       * Constructor which takes the name of the property that will be used in the transformation and
97       * assumes <code>ignoreNull</code> to be <code>false</code>.
98       *
99       * @param propertyName The name of the property that will be used in the transformation.
100      * @throws IllegalArgumentException If the <code>propertyName</code> is <code>null</code> or
101      * empty.
102      */
103     public BeanToPropertyValueTransformer(String propertyName) {
104         this(propertyName, false);
105     }
106 
107     /**
108      * Constructs a Transformer and sets ignoreNull.
109      * Constructor which takes the name of the property that will be used in the transformation and
110      * a boolean which determines whether <code>null</code> objects in the property path will
111      * genenerate an <code>IllegalArgumentException</code> or not.
112      *
113      * @param propertyName The name of the property that will be used in the transformation.
114      * @param ignoreNull Determines whether <code>null</code> objects in the property path will
115      * genenerate an <code>IllegalArgumentException</code> or not.
116      * @throws IllegalArgumentException If the <code>propertyName</code> is <code>null</code> or
117      * empty.
118      */
119     public BeanToPropertyValueTransformer(String propertyName, boolean ignoreNull) {
120         super();
121 
122         if ((propertyName != null) && (propertyName.length() > 0)) {
123             this.propertyName = propertyName;
124             this.ignoreNull = ignoreNull;
125         } else {
126             throw new IllegalArgumentException(
127                 "propertyName cannot be null or empty");
128         }
129     }
130 
131     /**
132      * Returns the value of the property named in the transformer's constructor for
133      * the object provided. If any object in the property path leading up to the target property is
134      * <code>null</code> then the outcome will be based on the value of the <code>ignoreNull</code>
135      * attribute. By default, <code>ignoreNull</code> is <code>false</code> and would result in an
136      * <code>IllegalArgumentException</code> if an object in the property path leading up to the
137      * target property is <code>null</code>.
138      *
139      * @param object The object to be transformed.
140      * @return The value of the property named in the transformer's constructor for the object
141      * provided.
142      * @throws IllegalArgumentException If an IllegalAccessException, InvocationTargetException, or
143      * NoSuchMethodException is thrown when trying to access the property specified on the object
144      * provided. Or if an object in the property path provided is <code>null</code> and
145      * <code>ignoreNull</code> is set to <code>false</code>.
146      */
147     public Object transform(Object object) {
148        
149         Object propertyValue = null;
150 
151         try {
152             propertyValue = PropertyUtils.getProperty(object, propertyName);
153         } catch (IllegalArgumentException e) {
154             final String errorMsg = "Problem during transformation. Null value encountered in property path...";
155 
156             if (ignoreNull) {
157                 log.warn("WARNING: " + errorMsg, e);
158             } else {
159                 log.error("ERROR: " + errorMsg, e);
160                 throw e;
161             }
162         } catch (IllegalAccessException e) {
163             final String errorMsg = "Unable to access the property provided.";
164             log.error(errorMsg, e);
165             throw new IllegalArgumentException(errorMsg);
166         } catch (InvocationTargetException e) {
167             final String errorMsg = "Exception occurred in property's getter";
168             log.error(errorMsg, e);
169             throw new IllegalArgumentException(errorMsg);
170         } catch (NoSuchMethodException e) {
171             final String errorMsg = "No property found for name [" +
172                 propertyName + "]";
173             log.error(errorMsg, e);
174             throw new IllegalArgumentException(errorMsg);
175         }
176 
177         return propertyValue;
178     }
179 
180     /**
181      * Returns the name of the property that will be used in the transformation of the bean.
182      *
183      * @return The name of the property that will be used in the transformation of the bean.
184      */
185     public String getPropertyName() {
186         return propertyName;
187     }
188 
189     /**
190      * Returns the flag which determines whether <code>null</code> objects in the property path will
191      * genenerate an <code>IllegalArgumentException</code> or not. If set to <code>true</code> then
192      * if any objects in the property path evaluate to <code>null</code> then the
193      * <code>IllegalArgumentException</code> throw by <code>PropertyUtils</code> will be logged but
194      * not rethrown and <code>null</code> will be returned.  If set to <code>false</code> then if any
195      * objects in the property path evaluate to <code>null</code> then the
196      * <code>IllegalArgumentException</code> throw by <code>PropertyUtils</code> will be logged and
197      * rethrown.
198      *
199      * @return The flag which determines whether <code>null</code> objects in the property path will
200      * genenerate an <code>IllegalArgumentException</code> or not.
201      */
202     public boolean isIgnoreNull() {
203         return ignoreNull;
204     }
205 }