I have a POJO, and a (currently not-yet-built) class that will return Lists of it. I\'d like to automatically generate the code necessary for the POJO to be accessed as a Map. I
Here's my own implementation without any dependencies. Rather than make a copy of the object's state, it implements a live Map over the pojo. Android doesn't support java.beans, but you can use openbeans instead.
import java.beans.*; // Or, import com.googlecode.openbeans.*
import java.util.*;
public class BeanMap extends AbstractMap {
private static final Object[] NO_ARGS = new Object[] {};
private HashMap properties;
private Object bean;
public BeanMap(Object bean) throws IntrospectionException {
this.bean = bean;
properties = new HashMap();
BeanInfo info = Introspector.getBeanInfo(bean.getClass());
for(PropertyDescriptor property : info.getPropertyDescriptors()) {
properties.put(property.getName(), property);
}
}
@Override public Object get(Object key) {
PropertyDescriptor property = properties.get(key);
if(property == null)
return null;
try {
return property.getReadMethod().invoke(bean, NO_ARGS);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override public Object put(String key, Object value) {
PropertyDescriptor property = properties.get(key);
try {
return property.getWriteMethod().invoke(bean, new Object[] {value});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override public Set> entrySet() {
HashSet> result = new HashSet>(properties.size() * 2);
for(PropertyDescriptor property : properties.values()) {
String key = property.getName();
Object value;
try {
value = property.getReadMethod().invoke(bean, NO_ARGS);
} catch (Exception e) {
throw new RuntimeException(e);
}
result.add(new PropertyEntry(key, value));
}
return Collections.unmodifiableSet(result);
}
@Override public int size() { return properties.size(); }
@Override public boolean containsKey(Object key) {
return properties.containsKey(key);
}
class PropertyEntry extends AbstractMap.SimpleEntry {
PropertyEntry(String key, Object value) {
super(key, value);
}
@Override public Object setValue(Object value) {
super.setValue(value);
return BeanMap.this.put(getKey(), value);
}
}
}