vendredi 14 décembre 2018

Re-create (generic) member and populate/assign field member(s) via Java reflection

I have a set of classes with any number of non-custom members — just primitives, wrappers, etc.; some of them can be annotated with @Encrypted in order to be processed differently. All types implement Envelope.

I'm creating two Maps (based on a given type), storing the "field name" (as the key) and the "field value" (as the value).

The problem is when I try to recreate the types again based on the Maps. This is what I have so far:

import io.shido.domain.Envelope;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.util.Map;

public final class Factory<T extends Envelope> {
  private final Map<String, Object> regularMembers;

  private final Map<String, Object> secureMembers;

  public Factory(final Map<String, Object> regularMembers, final Map<String, Object> secureMembers) {
    this.regularMembers = regularMembers;
    this.secureMembers = secureMembers;
  }

  public T build() {
    try {
      final ParameterizedType superClass = (ParameterizedType) getClass().getGenericSuperclass(); // This doesn't work >:(
      final Class<T> type = (Class<T>) superClass.getActualTypeArguments()[0];
      final T result = type.newInstance();
      regularMembers.forEach((fieldName, fieldValue) -> assign(result, fieldName, fieldValue));
      secureMembers.forEach((fieldName, fieldValue) -> assign(result, fieldName, fieldValue));
      return result;
    } catch (final Exception e) {
      logger.error("Cannot build type based on input parameters due to:", e);
      throw new IllegalStateException(e.toString());
    }
  }

  private void assign(final T type, final String fieldName, final Object fieldValue) {
    try {
      FieldUtils.getField(type.getClass(), fieldName).set(type, fieldValue);
    } catch (final IllegalAccessException e) {
      e.printStackTrace();
    }
  }
}

Any clues how to approach this? I can use any library.


The only restrictions I have is that the current types don't have setters — and I can't add those, and I'm using Java 8.

For instance, this is an example:

public final class ExampleType implements Envelope {
  @Encrypted
  private String first;

  private String second;

  @Encrypted
  private String third;

  public ExampleType() { }

  public ExampleType(final String first, final String second, final String third) {
    this.first = first;
    this.second = second;
    this.third = third;
  }

  public String getFirst() { return first; }

  public String getSecond() { return second; }

  public String getThird() { return third; }
}





Aucun commentaire:

Enregistrer un commentaire