PropertyUtils { public static Object setPropertyValue(Object context, String property, Object value) { if (property.contains(".")) { final String[] split = property.split("\\.", 2); final Object propertyValue = getPropertyValue(context, split[0]); if (propertyValue == null) { throw new IllegalStateException("Root property " + split[0] + " was null when reading " + property); } return setPropertyValue(propertyValue, split[1], value); } Method setter = null; final String setterName = "set" + StringUtils.capitalize(property); if (value != null) { setter = ReflectionUtils.findMethod(context.getClass(), setterName, value.getClass()); } else { for (Method method : ReflectionUtils.getAllDeclaredMethods(context.getClass())) { if (method.getName().equals(setterName) && method.getParameterTypes().length == 1 && !method .getParameterTypes()[0].isPrimitive()) { setter = method; break; } } } if (setter != null) { try { setter.invoke(context, value); return context; } catch (Exception e) { throw new IllegalStateException("Failed to set property value through the setter method " + setter); } } else { final Field field = ReflectionUtils.findField(context.getClass(), property); if (field != null) { if (Modifier.isFinal(field.getModifiers())) { field.setAccessible(true); } try { field.set(context, value); return context; } catch (Exception e) { throw new IllegalStateException("Failed to set property value through the field " + field); } } } throw new IllegalStateException("Failed to find property " + property + " on " + context.getClass()); } private  PropertyUtils(); static Object getPropertyValue(Object context, String property); static Object setPropertyValue(Object context, String property, Object value); static PropertyDescriptor getPropertyDescriptor(Class<?> domainType, String expression); static Class<?> getTypeOf(Class<?> type); static String getPropertyName(Method getter);  }
@Test public void testSettingImmediatePropertyValueUsingField() throws Exception { final ClassWithNoGetters object = new ClassWithNoGetters(); final Field id = Objects.requireNonNull(ReflectionUtils.findField(ClassWithNoGetters.class, "id")); id.setAccessible(true); final String value = "12345"; PropertyUtils.setPropertyValue(object, "id", value); assertThat(id.get(object), Matchers.is(value)); }
@Test(expectedExceptions = IllegalStateException.class) public void testSettingImmediatePropertyValueUsingErrorThrowingSetter() { PropertyUtils.setPropertyValue(new ClassWithErrorThrowingAccessors(), "id", ""); }
@Test public void testSettingImmediateFinalField() { PropertyUtils.setPropertyValue(new ClassWithFinalId(), "id", ""); }
@Test(expectedExceptions = IllegalStateException.class) public void testSettingUnknownProperty() { PropertyUtils.setPropertyValue(new Person(), "xyz", ""); }
@Test public void testSettingPropertyThroughSetters() { final Person person = new Person(); final String value = "123"; final Object changed = PropertyUtils.setPropertyValue(person, "id", value); assertThat(changed, Matchers.is(person)); assertThat(person.getId(), is(value)); }
@Test public void testSettingNestedProperty() { final Person person = new Person().setAddress(new Address().setZip(new Zip())); final String value = "Capital"; final Object changed = PropertyUtils.setPropertyValue(person, "address.zip.area", value); assertThat(changed, Matchers.is(person.getAddress().getZip())); assertThat(person.getAddress().getZip().getArea(), is(value)); }
@Test public void testSettingPropertyToNullThroughASetter() { final Person person = new Person().setId("1234"); PropertyUtils.setPropertyValue(person, "id", null); assertThat(person.getId(), is(nullValue())); }
@Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "Failed to set property value through the field .*") public void testSettingPrimitiveValueToNullThroughSetter() { PropertyUtils.setPropertyValue(new ClassWithPrimitiveField(), "position", null); }
@Test(expectedExceptions = IllegalStateException.class) public void testSettingNestedPropertyWhenParentPropertyIsNull() { PropertyUtils.setPropertyValue(new Person(), "address.zip", new Zip()); }