I'm trying to transform an object to a flat representation. I'm not talking CSV or toString method.
The properties I'm interested in are annotated with a @Field annotation. The value of the annotation will be used to match to a transformation map(not shown here) that will determine how a property will be transformed.
I was able to come up with a piece of code that uses reflection. It creates a fieldName->Method map. For example, given the Client class below, the Map will have 'name' pointing to a Method object that corresponds to the getName() - see below. Then I can invoke the appropriate method on any instance of the Client class for any property.
How do I deal with nested properties. For example, given the Currency class below, how do I get a Method object that will call Client.accounts[1].currency.code?
public class Client{
@Field( value = "name")
public String getName(){...}
@Field( value = "accounts" )
public List<Account> getAccounts(){...}
}
public class Account{
@Field( value = "acctNum")
public Long getAcctNum(){...}
@Field( value = "currency" )
public Currency getCurrency(){...}
}
public class Currency{
@Field( value = "code" )
public String getCode(){...}
}
First I'm creating a map of fieldName to Method. Something that I plan to do only once, and then reuse for object instances.
Map<String, Method> fieldMap = new HashMap();
for( Method method : Client.class.getDeclaredMethods() ){
Annotation annotation = method.getAnnotation(com.acme.Field.class);
if( annotation == null) {
continue;
}
com.acme.Field fieldMapping = (com.acme.mapping.Field) annotation;
String fieldName = fieldMapping.value();
fieldMap.put(fieldName, method);
}
Here's how I plan to reuse it
Client client = new Client();
for( Map.Entry<String, Method> entry : fieldMap.entrySet() ){
System.out.println(entry.getKey()+" -> "+entry.getValue().invoke(client, null));
}
Aucun commentaire:
Enregistrer un commentaire