View Javadoc
1   /*
2    * Copyright 2002-2014 the original author or authors.
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.springframework.beans;
18  
19  import org.junit.Rule;
20  import org.junit.Test;
21  import org.junit.rules.ExpectedException;
22  
23  import static org.hamcrest.CoreMatchers.*;
24  import static org.junit.Assert.*;
25  
26  /**
27   *
28   * @author Stephane Nicoll
29   */
30  public abstract class AbstractConfigurablePropertyAccessorTests {
31  
32  	@Rule
33  	public final ExpectedException thrown = ExpectedException.none();
34  
35  
36  	protected abstract ConfigurablePropertyAccessor createAccessor(Object target);
37  
38  	@Test
39  	public void isReadableProperty() {
40  		ConfigurablePropertyAccessor accessor = createAccessor(new Simple("John", 2));
41  
42  		assertThat(accessor.isReadableProperty("name"), is(true));
43  	}
44  
45  	@Test
46  	public void isReadablePropertyNotReadable() {
47  		ConfigurablePropertyAccessor accessor = createAccessor(new NoRead());
48  
49  		assertFalse(accessor.isReadableProperty("age"));
50  	}
51  
52  	/**
53  	 * Shouldn't throw an exception: should just return false
54  	 */
55  	@Test
56  	public void isReadablePropertyNoSuchProperty() {
57  		ConfigurablePropertyAccessor accessor = createAccessor(new NoRead());
58  
59  		assertFalse(accessor.isReadableProperty("xxxxx"));
60  	}
61  
62  	@Test
63  	public void isReadablePropertyNull() {
64  		ConfigurablePropertyAccessor accessor = createAccessor(new NoRead());
65  
66  		thrown.expect(IllegalArgumentException.class);
67  		accessor.isReadableProperty(null);
68  	}
69  
70  	@Test
71  	public void isWritableProperty() {
72  		ConfigurablePropertyAccessor accessor = createAccessor(new Simple("John", 2));
73  
74  		assertThat(accessor.isWritableProperty("name"), is(true));
75  	}
76  
77  	@Test
78  	public void isWritablePropertyNull() {
79  		ConfigurablePropertyAccessor accessor = createAccessor(new NoRead());
80  
81  		thrown.expect(IllegalArgumentException.class);
82  		accessor.isWritableProperty(null);
83  	}
84  
85  	@Test
86  	public void isWritablePropertyNoSuchProperty() {
87  		ConfigurablePropertyAccessor accessor = createAccessor(new NoRead());
88  
89  		assertFalse(accessor.isWritableProperty("xxxxx"));
90  	}
91  
92  	@Test
93  	public void getSimpleProperty() {
94  		Simple simple = new Simple("John", 2);
95  		ConfigurablePropertyAccessor accessor = createAccessor(simple);
96  		assertThat(accessor.getPropertyValue("name"), is("John"));
97  	}
98  
99  	@Test
100 	public void getNestedProperty() {
101 		Person person = createPerson("John", "London", "UK");
102 		ConfigurablePropertyAccessor accessor = createAccessor(person);
103 		assertThat(accessor.getPropertyValue("address.city"), is("London"));
104 	}
105 
106 	@Test
107 	public void getNestedDeepProperty() {
108 		Person person = createPerson("John", "London", "UK");
109 		ConfigurablePropertyAccessor accessor = createAccessor(person);
110 
111 		assertThat(accessor.getPropertyValue("address.country.name"), is("UK"));
112 	}
113 
114 	@Test
115 	public void getPropertyIntermediateFieldIsNull() {
116 		Person person = createPerson("John", "London", "UK");
117 		person.address = null;
118 		ConfigurablePropertyAccessor accessor = createAccessor(person);
119 
120 		try {
121 			accessor.getPropertyValue("address.country.name");
122 			fail("Should have failed to get value with null intermediate path");
123 		}
124 		catch (NullValueInNestedPathException e) {
125 			assertEquals("address", e.getPropertyName());
126 			assertEquals(Person.class, e.getBeanClass());
127 		}
128 	}
129 
130 	@Test
131 	public void getPropertyIntermediateFieldIsNullWithAutoGrow() {
132 		Person person = createPerson("John", "London", "UK");
133 		person.address = null;
134 		ConfigurablePropertyAccessor accessor = createAccessor(person);
135 		accessor.setAutoGrowNestedPaths(true);
136 
137 		assertEquals("DefaultCountry", accessor.getPropertyValue("address.country.name"));
138 	}
139 
140 	@Test
141 	public void getUnknownField() {
142 		Simple simple = new Simple("John", 2);
143 		ConfigurablePropertyAccessor accessor = createAccessor(simple);
144 
145 		try {
146 			accessor.getPropertyValue("foo");
147 			fail("Should have failed to get an unknown field.");
148 		}
149 		catch (NotReadablePropertyException e) {
150 			assertEquals(Simple.class, e.getBeanClass());
151 			assertEquals("foo", e.getPropertyName());
152 		}
153 	}
154 
155 	@Test
156 	public void getUnknownNestedField() {
157 		Person person = createPerson("John", "London", "UK");
158 		ConfigurablePropertyAccessor accessor = createAccessor(person);
159 
160 		thrown.expect(NotReadablePropertyException.class);
161 		accessor.getPropertyValue("address.bar");
162 	}
163 
164 	@Test
165 	public void setSimpleProperty() {
166 		Simple simple = new Simple("John", 2);
167 		ConfigurablePropertyAccessor accessor = createAccessor(simple);
168 
169 		accessor.setPropertyValue("name", "SomeValue");
170 
171 		assertThat(simple.name, is("SomeValue"));
172 		assertThat(simple.getName(), is("SomeValue"));
173 	}
174 
175 	@Test
176 	public void setNestedProperty() {
177 		Person person = createPerson("John", "Paris", "FR");
178 		ConfigurablePropertyAccessor accessor = createAccessor(person);
179 
180 		accessor.setPropertyValue("address.city", "London");
181 		assertThat(person.address.city, is("London"));
182 	}
183 
184 	@Test
185 	public void setNestedDeepProperty() {
186 		Person person = createPerson("John", "Paris", "FR");
187 		ConfigurablePropertyAccessor accessor = createAccessor(person);
188 
189 		accessor.setPropertyValue("address.country.name", "UK");
190 		assertThat(person.address.country.name, is("UK"));
191 	}
192 
193 	@Test
194 	public void setPropertyIntermediateFieldIsNull() {
195 		Person person = createPerson("John", "Paris", "FR");
196 		person.address.country = null;
197 		ConfigurablePropertyAccessor accessor = createAccessor(person);
198 
199 		try {
200 			accessor.setPropertyValue("address.country.name", "UK");
201 			fail("Should have failed to set value with intermediate null value");
202 		}
203 		catch (NullValueInNestedPathException e) {
204 			assertEquals("address.country", e.getPropertyName());
205 			assertEquals(Person.class, e.getBeanClass());
206 		}
207 		assertThat(person.address.country, is(nullValue())); // Not touched
208 	}
209 
210 	@Test
211 	public void setPropertyIntermediateFieldIsNullWithAutoGrow() {
212 		Person person = createPerson("John", "Paris", "FR");
213 		person.address.country = null;
214 		ConfigurablePropertyAccessor accessor = createAccessor(person);
215 		accessor.setAutoGrowNestedPaths(true);
216 
217 		accessor.setPropertyValue("address.country.name", "UK");
218 		assertThat(person.address.country.name, is("UK"));
219 	}
220 
221 	@Test
222 	public void setUnknownField() {
223 		Simple simple = new Simple("John", 2);
224 		ConfigurablePropertyAccessor accessor = createAccessor(simple);
225 
226 		try {
227 			accessor.setPropertyValue("foo", "value");
228 			fail("Should have failed to set an unknown field.");
229 		}
230 		catch (NotWritablePropertyException e) {
231 			assertEquals(Simple.class, e.getBeanClass());
232 			assertEquals("foo", e.getPropertyName());
233 		}
234 	}
235 
236 	@Test
237 	public void setUnknownNestedField() {
238 		Person person = createPerson("John", "Paris", "FR");
239 		ConfigurablePropertyAccessor accessor = createAccessor(person);
240 
241 		thrown.expect(NotWritablePropertyException.class);
242 		accessor.setPropertyValue("address.bar", "value");
243 	}
244 
245 
246 	@Test
247 	public void propertyType() {
248 		Person person = createPerson("John", "Paris", "FR");
249 		ConfigurablePropertyAccessor accessor = createAccessor(person);
250 
251 		assertEquals(String.class, accessor.getPropertyType("address.city"));
252 	}
253 
254 	@Test
255 	public void propertyTypeUnknownField() {
256 		Simple simple = new Simple("John", 2);
257 		ConfigurablePropertyAccessor accessor = createAccessor(simple);
258 
259 		assertThat(accessor.getPropertyType("foo"), is(nullValue()));
260 	}
261 
262 	@Test
263 	public void propertyTypeDescriptor() {
264 		Person person = createPerson("John", "Paris", "FR");
265 		ConfigurablePropertyAccessor accessor = createAccessor(person);
266 
267 		assertThat(accessor.getPropertyTypeDescriptor("address.city"), is(notNullValue()));
268 	}
269 
270 	@Test
271 	public void propertyTypeDescriptorUnknownField() {
272 		Simple simple = new Simple("John", 2);
273 		ConfigurablePropertyAccessor accessor = createAccessor(simple);
274 
275 		assertThat(accessor.getPropertyTypeDescriptor("foo"), is(nullValue()));
276 	}
277 
278 
279 	private Person createPerson(String name, String city, String country) {
280 		return new Person(name, new Address(city, country));
281 	}
282 
283 
284 	private static class Simple {
285 
286 		private String name;
287 
288 		private Integer integer;
289 
290 		private Simple(String name, Integer integer) {
291 			this.name = name;
292 			this.integer = integer;
293 		}
294 
295 		public String getName() {
296 			return name;
297 		}
298 
299 		public void setName(String name) {
300 			this.name = name;
301 		}
302 
303 		public Integer getInteger() {
304 			return integer;
305 		}
306 
307 		public void setInteger(Integer integer) {
308 			this.integer = integer;
309 		}
310 	}
311 
312 	private static class Person {
313 		private String name;
314 
315 		private Address address;
316 
317 		private Person(String name, Address address) {
318 			this.name = name;
319 			this.address = address;
320 		}
321 
322 		public Person() {
323 		}
324 
325 		public String getName() {
326 			return name;
327 		}
328 
329 		public void setName(String name) {
330 			this.name = name;
331 		}
332 
333 		public Address getAddress() {
334 			return address;
335 		}
336 
337 		public void setAddress(Address address) {
338 			this.address = address;
339 		}
340 	}
341 
342 	private static class Address {
343 		private String city;
344 
345 		private Country country;
346 
347 		private Address(String city, String country) {
348 			this.city = city;
349 			this.country = new Country(country);
350 		}
351 
352 		public Address() {
353 			this("DefaultCity", "DefaultCountry");
354 		}
355 
356 		public String getCity() {
357 			return city;
358 		}
359 
360 		public void setCity(String city) {
361 			this.city = city;
362 		}
363 
364 		public Country getCountry() {
365 			return country;
366 		}
367 
368 		public void setCountry(Country country) {
369 			this.country = country;
370 		}
371 	}
372 
373 	private static class Country {
374 		private String name;
375 
376 		public Country(String name) {
377 			this.name = name;
378 		}
379 
380 		public Country() {
381 			this(null);
382 		}
383 
384 		public String getName() {
385 			return name;
386 		}
387 
388 		public void setName(String name) {
389 			this.name = name;
390 		}
391 	}
392 
393 
394 	@SuppressWarnings("unused")
395 	static class NoRead {
396 
397 		public void setAge(int age) {
398 		}
399 	}
400 }