PropertyUtils { public static PropertyDescriptor getPropertyDescriptor(Class<?> domainType, String expression) { String search = expression; final String followUp; if (search.contains("_")) { final String[] split = search.split("_", 2); search = split[0]; followUp = split[1]; } else { followUp = ""; } Class<?> context = domainType; final DocumentReader reader = new DefaultDocumentReader(search); final List<String> tokens = new ArrayList<>(); while (reader.hasMore()) { tokens.add(reader.expect("[A-Z][a-z]*")); } int cursor = 0; final StringBuilder path = new StringBuilder(); while (cursor < tokens.size()) { boolean found = false; for (int i = tokens.size(); i >= cursor; i--) { final String propertyName = getPropertyName(tokens, cursor, i); final Method getter = ReflectionUtils.findMethod(context, "get" + StringUtils.capitalize(propertyName)); if (getter != null) { context = getter.getReturnType(); cursor = i; found = true; path.append(".").append(propertyName); break; } final Field field = ReflectionUtils.findField(context, propertyName); if (field != null) { context = field.getType(); cursor = i; found = true; path.append(".").append(propertyName); break; } } if (!found) { throw new IllegalStateException( "Could not find property `" + getPropertyName(tokens, cursor, tokens.size()) + "` on `" + context + "`"); } } if (!followUp.isEmpty()) { final PropertyDescriptor descriptor = getPropertyDescriptor(context, followUp); return new ImmutablePropertyDescriptor(path.substring(1) + "." + descriptor.getPath(), descriptor.getType()); } return new ImmutablePropertyDescriptor(path.substring(1), context); } 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 testFirstLevelPropertyWithoutExplicitBreaking() { final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(Person.class, "AddressZip"); assertThat(descriptor, is(notNullValue())); assertThat(descriptor.getPath(), is("addressZip")); assertThat(descriptor.getType(), equalTo((Class) Zip.class)); }
@Test public void testPropertyWithExplicitBreaking() { final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(Person.class, "Address_Zip"); assertThat(descriptor, is(notNullValue())); assertThat(descriptor.getPath(), is("address.zip")); assertThat(descriptor.getType(), equalTo((Class) Zip.class)); }
@Test public void testMultiLevelPropertyWithoutExplicitBreaking() { final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(Person.class, "AddressZipPrefix"); assertThat(descriptor, is(notNullValue())); assertThat(descriptor.getPath(), is("addressZip.prefix")); assertThat(descriptor.getType(), equalTo((Class) String.class)); }
@Test public void testMultiLevelPropertyWithExplicitBreaking() { final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(Person.class, "Address_ZipPrefix"); assertThat(descriptor, is(notNullValue())); assertThat(descriptor.getPath(), is("address.zip.prefix")); assertThat(descriptor.getType(), equalTo((Class) String.class)); }
@Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "Could not find property `xyz` on `class .*?\\.Person`") public void testNonExistingFirstLevelProperty() { PropertyUtils.getPropertyDescriptor(Person.class, "Xyz"); }
@Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "Could not find property `xyz` on `class .*?\\.Zip`") public void testNonExistingThirdLevelProperty() { PropertyUtils.getPropertyDescriptor(Person.class, "Address_ZipXyz"); }
@Test public void testFirstLevelPropertyWithoutExplicitBreakingUsingFields() { final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(NoAccessorPerson.class, "AddressZip"); assertThat(descriptor, is(notNullValue())); assertThat(descriptor.getPath(), is("addressZip")); assertThat(descriptor.getType(), equalTo((Class) Zip.class)); }
@Test public void testPropertyWithExplicitBreakingUsingFields() { final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(NoAccessorPerson.class, "Address_Zip"); assertThat(descriptor, is(notNullValue())); assertThat(descriptor.getPath(), is("address.zip")); assertThat(descriptor.getType(), equalTo((Class) Zip.class)); }
@Test public void testMultiLevelPropertyWithoutExplicitBreakingUsingFields() { final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(NoAccessorPerson.class, "AddressZipPrefix"); assertThat(descriptor, is(notNullValue())); assertThat(descriptor.getPath(), is("addressZip.prefix")); assertThat(descriptor.getType(), equalTo((Class) String.class)); }
@Test public void testMultiLevelPropertyWithExplicitBreakingUsingFields() { final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(NoAccessorPerson.class, "Address_ZipPrefix"); assertThat(descriptor, is(notNullValue())); assertThat(descriptor.getPath(), is("address.zip.prefix")); assertThat(descriptor.getType(), equalTo((Class) String.class)); }
@Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "Could not find property `xyz` on `class .*?\\.NoAccessorPerson`") public void testNonExistingFirstLevelPropertyUsingFields() { PropertyUtils.getPropertyDescriptor(NoAccessorPerson.class, "Xyz"); }
@Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "Could not find property `xyz` on `class .*?\\.Zip`") public void testNonExistingThirdLevelPropertyUsingFields() { PropertyUtils.getPropertyDescriptor(NoAccessorPerson.class, "Address_ZipXyz"); }
@Test(expectedExceptions = ParserException.class, expectedExceptionsMessageRegExp = "Expected pattern '.*?' was not encountered.*") public void testPropertyPathThatDoesNotStartWithCapitalLetter() { PropertyUtils.getPropertyDescriptor(Person.class, "address"); }
@Test public void testFirstLevelPropertyPath() { final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(Person.class, "Address"); assertThat(descriptor, is(notNullValue())); assertThat(descriptor.getPath(), is("address")); assertThat(descriptor.getType(), equalTo((Class) Address.class)); }