FieldBasedAccessor.java
package org.microspace.specific;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import org.microspace.annotation.IndexType;
import org.microspace.annotation.SpaceRecord;
import org.microspace.annotation.ThreadId;
import org.microspace.table.column.Accessor;
import org.microspace.table.column.GetSetPair;
/**
* A simple object that has only fields can be accessed by this Class.
* <pre>
* public class {
* public String id;
* public BigDecimal price;
* public String name;
* }
* </pre>
* The first n fields can be specified. The first field has to be the primaryKey.
* <p>
* Currently {@link ThreadId ThreadId} is not supported.
* @author gsinai
* @version 2012-01-29
*/
public class FieldBasedAccessor<T> implements Accessor<T> {
private GetSetPair<T> primaryKeyGetter;
private List<GetSetPair<T>> getSetPairs = new ArrayList<GetSetPair<T>> ();
private TreeMap<String, GetSetPair<T>> getSetPairsByName = new TreeMap<String, GetSetPair<T>> ();
private Class<T> targetClass;
private boolean localRecord;
private boolean updatableRecord;
public FieldBasedAccessor (Class<T> targetClass, int indexedFieldCount) {
this.targetClass = targetClass;
for (Field field : targetClass.getFields()) {
if (!Modifier.isFinal(field.getModifiers()) && !Modifier.isPublic(field.getModifiers())) {
continue;
}
FieldBasedGetterSetter<T> pair = new FieldBasedGetterSetter<T> (field);
if (getSetPairs.size() < indexedFieldCount) {
pair.setIndexType(getIndexType (field));
}
if (primaryKeyGetter == null) {
primaryKeyGetter = pair;
}
pair.setIndex(getSetPairs.size());
getSetPairsByName.put(pair.getName(), pair);
getSetPairs.add (pair);
}
if (primaryKeyGetter == null) {
throw new IllegalArgumentException ("No primary key defined for " + targetClass);
}
localRecord = false;
updatableRecord = false;
if (targetClass.isAnnotationPresent(SpaceRecord.class)) {
SpaceRecord annotation = targetClass.getAnnotation(SpaceRecord.class);
localRecord = annotation.local();
updatableRecord = annotation.updatable();
}
}
public GetSetPair<T> getPrimaryKeyGetSetPair() {
return primaryKeyGetter;
}
public List<GetSetPair<T>> getGetSetPairs() {
return getSetPairs;
}
public GetSetPair<T> getGetSetPair (String name) {
return getSetPairsByName.get(name);
}
public T getBlankObject () {
return MethodUtils.getBlank (targetClass);
}
public Class<T> getTargetClass() {
return targetClass;
}
protected IndexType getIndexType (Field field) {
if (Comparable.class.isAssignableFrom(field.getType())) {
return IndexType.SORTED;
} else {
return IndexType.HASHED;
}
}
@Override
public GetSetPair<T> getThreadIdGetSetPair() {
return null;
}
@Override
public GetSetPair<T> getPartitionIdGetSetPair() {
return null;
}
@Override
public boolean isLocalRecord() {
return localRecord;
}
@Override
public boolean isUpdatableRecord() {
return updatableRecord;
}
}