package osgi.dto.provider;
import java.lang.reflect.Field;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.osgi.dto.DTO;
public class DTOMap extends AbstractMap<String,Object> {
private final DTOsProvider dtos;
private final Object dto;
private final Field[] fields;
public DTOMap(DTOsProvider dtOsProvider, Object dto) {
this.dtos = dtOsProvider;
this.dto = dto;
this.fields = dtos.getFields(dto);
}
@Override
public int size() {
return fields.length;
}
@Override
public boolean isEmpty() {
return fields.length == 0;
}
@Override
public boolean containsKey(Object key) {
if (!(key instanceof String))
return false;
return dtos.bsearch(fields, 0, fields.length, (String) key) >= 0;
}
@Override
public boolean containsValue(Object value) {
for (Field f : fields) {
Object o;
try {
o = f.get(dto);
if (o == value)
return true;
if (o == null)
return false;
return o.equals(value);
}
catch (IllegalArgumentException | IllegalAccessException e) {
// Ignore since we only have public fields
}
}
return false;
}
@Override
public Object get(Object key) {
try {
if (!(key instanceof String))
return null;
Field field = dtos.getField(fields, (String) key);
if (field == null)
return null;
Object o = field.get(dto);
if (o instanceof DTO) {
return new DTOMap(dtos, o);
} else
return o;
}
catch (IllegalArgumentException | IllegalAccessException e) {
// cannot happen
return null;
}
}
@Override
public Set<java.util.Map.Entry<String,Object>> entrySet() {
return new AbstractSet<Map.Entry<String,Object>>() {
@Override
public Iterator<java.util.Map.Entry<String,Object>> iterator() {
return new Iterator<Map.Entry<String,Object>>() {
int n = 0;
@Override
public boolean hasNext() {
return n < fields.length;
}
@Override
public java.util.Map.Entry<String,Object> next() {
final Field field = fields[n];
return new Map.Entry<String,Object>() {
@Override
public String getKey() {
return field.getName();
}
@Override
public Object getValue() {
try {
return field.get(dto);
}
catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public Object setValue(Object value) {
try {
Object old = field.get(dto);
field.set(dto,value);
return old;
}
catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
};
}
@Override
public void remove() {
throw new UnsupportedOperationException("A DTO map cannot remove entries");
}
};
}
@Override
public int size() {
return DTOMap.this.size();
}
};
}
}