Mapping read attributes to an existing model via Java Reflection API

Wednesday, June 30th, 2010

Here´s a way, how to map read Key / Value Pairs to a Model with the Java Reflection API.

First of all, let´s say you have a reader (e.g. a BufferedReader) which reads Key/Value Pairs. So you´ll get from one Line of the Reader something like this:

  name=fred
  surname=fart

Now you have a modell, which provides all the keys as attributes.

public class Person {
  private String name;
  private String surname;

...

setName(String newName) {
  this.name = newName;
}
setSurname(String newName) {
  this.name = newName;
}

...
}

now we´ll get to the reading routine

public class xxx {
  ...
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  ...

//this method reads the information e.g. with the help of an bufferedReader
  public Person readPersonInformation(PersonInformationObject pio) {

    ...
    Person newPerson = new Person();

    while ((line = reader.readLine()) != null) {
      parseReadPersonAttributes(newPerson, line);
    }
    ...
    return newPerson;
  }

/**this method parses the read information
* @newPerson the object, where the new value is beeing invoked on
* @codedInformation the read key-value line
**/
  private void parseReadPersonAttributes(Person newPerson, String codedInformation) {
    String information = codedInformation;
    //if there is noch equal symbol, than isnt able to be interpreted
    if (information.contains("=")) {
      String interpretedInformation[] = new String[2];
      interpretedInformation = information.split("=");
      if (interpretedInformation.length > 1) {
        //now for the Reflaction API
        Method personMethods[] = Person.class.getMethods();
        for (Method method : personMethods) {
          //find the setter Method for the Attribute
          if (method.getName().equalsIgnoreCase("set" + interpretedInformation[0])) {
            try {
              //now that a Method is found, try to invoke the method with the read Information
              method.invoke(newPerson, interpretedInformation[1]);
            } catch (Exception ex) {
              //errorhandling
            }
          }
        }
      }
    }
  }
}

The code searchs for a fitting setter Method in the Person Modell. If he finds a appropriate Method, its invoking this method on the given Person Object, in order to set the read Information

Note that if there are more keys read than there are attributes in the modell, you just have to add those attributes to the modell. I think that this is a good way, to map read information to a modell

One Response to “Mapping read attributes to an existing model via Java Reflection API”

  • Rafael Sierra

    Nice post. I just finished implementing the same thing for parsing a large amount of data that comes in a format like key1=val1,…,key20=val20
    The problem is that I also get data updates where I have input lines containing only a few key/value pairs.

    I kinda knew that reflection could help me here, but I’ve never used reflection before, so I didn’t do now. However your example has shown me how easy it is. One problem I see here, though, is that all setters must have the same signature, that is, setter( String), so either you overload the setters that don’t take String, or find other solution. I did it the expected way: populate a map with the input and then try to retrieve the keys, setting the ones that don’t return null.

    I like the reflection solution because, as you mention, the model can be extended/reduced without needing to modify the data writer nor the parser. The only concern I’d have is how much a performance hit will take the parsing by using reflection. I will test it when I find the time.

    Thanks.

    [Reply]

Leave a Reply