auto-matter icon indicating copy to clipboard operation
auto-matter copied to clipboard

Possible to add a `getFields` instance method?

Open bricejlin opened this issue 7 years ago • 1 comments

Any thoughts on introducing a getFields method to automatter objects? Would love to be able to iterate through an Automatter Object's fields. I have a usecase to check that at least one field is populated in the object and right now, I'm forced to manually check every field to get that.

bricejlin avatar Mar 16 '17 17:03 bricejlin

That sounds useful. Feel free to submit a PR =)

Meanwhile, here's an example of some utility methods for doing this using reflection.

public static void main(String... args) {
  Foobar foobar = new FoobarBuilder()
      .foo("hello world")
      .bar(17)
      .build();

  boolean anyPopulated = anyFieldPopulated(Foobar.class, foobar);

  System.out.println(anyPopulated);
}

static <T> boolean anyFieldPopulated(Class<T> cls, T o) {
  return getFields(cls)
      .map(field -> getValue(field, o))
      .filter(Objects::nonNull)
      // TODO: handle collections?
      .anyMatch(value -> value.getClass() != Optional.class ||
          ((Optional<?>) value).isPresent());
}

static Stream<Method> getFields(Class<?> cls) {
  return Stream.of(cls.getMethods())
      .filter(m -> m.getDeclaringClass() == cls)
      .filter(m -> !m.getReturnType().getName().endsWith("Builder"));
}

static Object getValue(Method m, Object o) {
  try {
    return m.invoke(o);
  } catch (IllegalAccessException | InvocationTargetException e) {
    throw new RuntimeException(e);
  }
}

danielnorberg avatar Mar 26 '17 15:03 danielnorberg