javareflectionapache-commons-beanutils

How to dynamically invoke a method with parameters instead of using Apache Commons BeanUtils PropertyUtils.getProperty()?


I'm currently using PropertyUtils.getProperty() from Apache Commons BeanUtils to evaluate nested property paths at runtime:

Object result = PropertyUtils.getProperty(object, "a.b.c");

This works well for standard JavaBean-style no-arg getter chains.

Now I have a method that requires a parameter, like this:

public String getInactiveReason(String customer);

And I need to dynamically invoke this method as part of a property path evaluation like: "a.b.c.inactiveReason"

But PropertyUtils.getProperty() does not support method calls with parameters, and throws a NoSuchMethodException if the method expects arguments.

Is there any library that supports this out of the box, or do I need to fully replace PropertyUtils with a custom evaluator?


Solution

  • Just use Object Graph Navigation Library ognl:ognl, although it is a bit tricky with type castings.

    class ObjectGraphTest {
      @Test
      void givenPersonWithNestedChild_whenGetNestedPropertyWithParameter_thenProperStringIsReturned() throws OgnlException {
        var person = new Person();
        person.setChild(new Child());
        Object root = person;
        Map<String, Object> values = Map.of("customer", "EXAMPLE CUSTOMER");
        var context = Ognl.createDefaultContext(root, values);
    
        var value = (String) Ognl.getValue("child.getInactiveReason(#customer)", context, person);
    
        assertThat(value).isEqualTo("Inactive reason for customer EXAMPLE CUSTOMER");
      }
    
      @Getter
      @Setter
      private static class Person {
        private Child child;
      }
    
      public static class Child {
        public String getInactiveReason(String customer) {
          return "Inactive reason for customer %s".formatted(customer);
        }
      }
    }
    

    Source: https://github.com/orphan-oss/ognl.