View Javadoc

1   /*
2    * Copyright 2006 Stephen Duncan Jr
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at http://www.apache.org/licenses/LICENSE-2.0
7    * 
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11   * License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  package com.stephenduncanjr.easymock;
15  
16  import static org.easymock.EasyMock.reportMatcher;
17  
18  import java.beans.PropertyDescriptor;
19  import java.lang.reflect.InvocationTargetException;
20  import java.lang.reflect.Method;
21  import java.util.Arrays;
22  import java.util.HashMap;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.apache.commons.beanutils.PropertyUtils;
28  
29  import com.stephenduncanjr.easymock.matcher.BeanProperty;
30  
31  /***
32   * Utilities for using EasyMock.
33   * 
34   * @author stephen.duncan (Stephen C. Duncan Jr.
35   *         <stephen.duncan@gmail.com>)
36   * @since 1.0
37   */
38  public class EasyMockPropertyUtils
39  {
40  	/*** Empty List. */
41  	private static final List<String> EMPTY = new LinkedList<String>();
42  
43  	/***
44  	 * Disables object creation.
45  	 */
46  	private EasyMockPropertyUtils()
47  	{
48  		// Hide constructor
49  	}
50  
51  	/***
52  	 * EasyMock matcher for the properties on the object to be matched being
53  	 * equal to the mapped value.
54  	 * 
55  	 * @param <T>
56  	 *        The type of object to match.
57  	 * @param inClass
58  	 *        The type of the object to match.
59  	 * @param properties
60  	 *        The map of property names to property values.
61  	 * @return fake return value for EasyMock use.
62  	 * @since 1.1
63  	 */
64  	public static <T> T propEq(@SuppressWarnings("unused")
65  	final Class<T> inClass, final Map<String, ?> properties)
66  	{
67  		reportMatcher(new BeanProperty(properties));
68  		return null;
69  	}
70  
71  	/***
72  	 * EasyMock matcher for the properties on the argument to match the
73  	 * properties on the given object.
74  	 * 
75  	 * @param <T>
76  	 *        The type of object to match.
77  	 * @param inClass
78  	 *        The type of the object to match.
79  	 * @param valuesObject
80  	 *        the object to match values against.
81  	 * @return fake return value for EasyMock use.
82  	 * @since 1.1
83  	 */
84  	public static <T> T propEq(@SuppressWarnings("unused")
85  	final Class<T> inClass, final Object valuesObject)
86  	{
87  		reportMatcher(new BeanProperty(retrieveAndFilterProperties(valuesObject, EMPTY)));
88  		return null;
89  	}
90  
91  	/***
92  	 * EasyMock matcher for the properties on the argument to match the
93  	 * properties on the given object, ignoring the properties named in the
94  	 * given list.
95  	 * 
96  	 * @param <T>
97  	 *        The type of object to match.
98  	 * @param inClass
99  	 *        The type of the object to match.
100 	 * @param valuesObject
101 	 *        the object to match values against.
102 	 * @param ignored
103 	 *        the list of property names to ignore.
104 	 * @return fake return value for EasyMock use.
105 	 * @since 1.1
106 	 */
107 	public static <T> T propEq(@SuppressWarnings("unused")
108 	final Class<T> inClass, final Object valuesObject, final List<String> ignored)
109 	{
110 		reportMatcher(new BeanProperty(retrieveAndFilterProperties(valuesObject, ignored)));
111 		return null;
112 	}
113 
114 	/***
115 	 * EasyMock matcher for the properties on the argument to match the
116 	 * properties on the given object, ignoring the properties named in the
117 	 * given array.
118 	 * 
119 	 * @param <T>
120 	 *        The type of object to match.
121 	 * @param inClass
122 	 *        The type of the object to match.
123 	 * @param valuesObject
124 	 *        the object to match values against.
125 	 * @param ignored
126 	 *        the list of property names to ignore.
127 	 * @return fake return value for EasyMock use.
128 	 * @since 1.1
129 	 */
130 	public static <T> T propEq(@SuppressWarnings("unused")
131 	final Class<T> inClass, final Object valuesObject, final String[] ignored)
132 	{
133 		reportMatcher(new BeanProperty(retrieveAndFilterProperties(valuesObject, Arrays.asList(ignored))));
134 		return null;
135 	}
136 
137 	/***
138 	 * EasyMock matcher for the property on the object to be matched being equal
139 	 * to the given value.
140 	 * 
141 	 * @param <T>
142 	 *        The type of object to match.
143 	 * @param inClass
144 	 *        The type of the object to match.
145 	 * @param property
146 	 *        the name of the property.
147 	 * @param value
148 	 *        The value of the property to ccompare against.
149 	 * @return fake return value for EasyMock use.
150 	 * @since 1.1
151 	 */
152 	public static <T> T propEq(@SuppressWarnings("unused")
153 	final Class<T> inClass, final String property, final Object value)
154 	{
155 		reportMatcher(new BeanProperty(property, value));
156 		return null;
157 	}
158 
159 	/***
160 	 * EasyMock matcher for the properties on the argument to match the
161 	 * properties on the given object.
162 	 * 
163 	 * @param <T>
164 	 *        The type of object to match.
165 	 * @param valuesObject
166 	 *        the object to match values against.
167 	 * @return fake return value for EasyMock use.
168 	 * @since 1.1
169 	 */
170 	public static <T> T propEq(final T valuesObject)
171 	{
172 		reportMatcher(new BeanProperty(retrieveAndFilterProperties(valuesObject, EMPTY)));
173 		return null;
174 	}
175 
176 	/***
177 	 * EasyMock matcher for the properties on the argument to match the
178 	 * properties on the given object, ignoring the properties named in the
179 	 * given list.
180 	 * 
181 	 * @param <T>
182 	 *        The type of object to match.
183 	 * @param valuesObject
184 	 *        the object to match values against.
185 	 * @param ignored
186 	 *        the list of property names to ignore.
187 	 * @return fake return value for EasyMock use.
188 	 * @since 1.1
189 	 */
190 	public static <T> T propEq(final T valuesObject, final List<String> ignored)
191 	{
192 		reportMatcher(new BeanProperty(retrieveAndFilterProperties(valuesObject, ignored)));
193 		return null;
194 	}
195 
196 	/***
197 	 * EasyMock matcher for the properties on the argument to match the
198 	 * properties on the given object, ignoring the properties named in the
199 	 * given array.
200 	 * 
201 	 * @param <T>
202 	 *        The type of object to match.
203 	 * @param valuesObject
204 	 *        the object to match values against.
205 	 * @param ignored
206 	 *        the list of property names to ignore.
207 	 * @return fake return value for EasyMock use.
208 	 * @since 1.1
209 	 */
210 	public static <T> T propEq(final T valuesObject, final String[] ignored)
211 	{
212 		reportMatcher(new BeanProperty(retrieveAndFilterProperties(valuesObject, Arrays.asList(ignored))));
213 		return null;
214 	}
215 
216 	/***
217 	 * EasyMock matcher for the properties on the object to be matched being
218 	 * equal to the mapped value.
219 	 * 
220 	 * @param <T>
221 	 *        The type of object to match.
222 	 * @param inClass
223 	 *        The type of the object to match.
224 	 * @param properties
225 	 *        The map of property names to property values.
226 	 * @return fake return value for EasyMock use.
227 	 * @deprecated As of 1.1, replaced by {@link #propEq(Class, Map)}
228 	 */
229 	@Deprecated
230 	public static <T> T propertiesEq(@SuppressWarnings("unused")
231 	final Class<T> inClass, final Map<String, ?> properties)
232 	{
233 		return EasyMockPropertyUtils.propertiesEq(inClass, properties);
234 	}
235 
236 	/***
237 	 * EasyMock matcher for the property on the object to be matched being equal
238 	 * to the given value.
239 	 * 
240 	 * @param <T>
241 	 *        The type of object to match.
242 	 * @param inClass
243 	 *        The type of the object to match.
244 	 * @param property
245 	 *        the name of the property.
246 	 * @param value
247 	 *        The value of the property to ccompare against.
248 	 * @return fake return value for EasyMock use. *
249 	 * @deprecated As of 1.1, replaced by {@link #propEq(Class, String, Object)}
250 	 */
251 	@Deprecated
252 	public static <T> T propertyEq(@SuppressWarnings("unused")
253 	final Class<T> inClass, final String property, final Object value)
254 	{
255 		return EasyMockPropertyUtils.propEq(inClass, property, value);
256 	}
257 
258 	/***
259 	 * Gets the properties and values from the object as a map, ignoring the
260 	 * properties specified.
261 	 * 
262 	 * @param bean
263 	 * @param ignoredProperties
264 	 * @return map of properties names to values.
265 	 */
266 	private static Map<String, Object> retrieveAndFilterProperties(final Object bean, final List<String> ignoredProperties)
267 	{
268 		final Map<String, Object> map = new HashMap<String, Object>();
269 
270 		try
271 		{
272 			for(final PropertyDescriptor p : PropertyUtils.getPropertyDescriptors(bean))
273 			{
274 				if(!ignoredProperties.contains(p.getName()) && !"class".equals(p.getName()))
275 				{
276 					final Method readMethod = p.getReadMethod();
277 					
278 					if (readMethod != null) {
279 						map.put(p.getName(), readMethod.invoke(bean));
280 					}
281 				}
282 			}
283 		}
284 		catch(final IllegalAccessException e)
285 		{
286 			throw new IllegalArgumentException(e);
287 		}
288 		catch(final InvocationTargetException e)
289 		{
290 			throw new IllegalArgumentException(e);
291 		}
292 
293 		return map;
294 	}
295 }