package meetup.beeno.mapping;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import meetup.beeno.HEntity;
import meetup.beeno.HIndex;
import meetup.beeno.HProperty;
import meetup.beeno.HRowKey;
import meetup.beeno.mapping.EntityMetadata.PropertyType;
/**
* Encapsulates the mapping of an entity class and its properties
* to an HBase table and columns.
*
* @author garyh
*
*/
public class EntityInfo {
private Class entityClass = null;
private String table = null;
private PropertyDescriptor keyProperty = null;
private List<FieldMapping> mappedProps = new ArrayList<FieldMapping>();
private Map<String, PropertyDescriptor> propertiesByName = new HashMap<String, PropertyDescriptor>();
private Map<PropertyDescriptor, FieldMapping> fieldsByProperty = new HashMap<PropertyDescriptor, FieldMapping>();
private Map<PropertyDescriptor, PropertyType> typesByProperty = new HashMap<PropertyDescriptor, PropertyType>();
private Map<PropertyDescriptor, List<IndexMapping>> indexesByProperty = new HashMap<PropertyDescriptor, List<IndexMapping>>();
public EntityInfo(Class clazz) {
this.entityClass = clazz;
}
public Class getEntityClass() { return this.entityClass; }
/**
* Returns the HBase table identified by the entity's {@link HEntity}
* annotation.
* @return
*/
public String getTablename() { return this.table; }
public void setTablename(String tablename) { this.table = tablename; }
/**
* Returns the java bean properties mapped by the entity's {@link HRowKey}
* annotation.
*
* @return
*/
public PropertyDescriptor getKeyProperty() { return this.keyProperty; }
public void setKeyProperty(PropertyDescriptor prop) { this.keyProperty = prop; }
public void addProperty(HProperty mapping, PropertyDescriptor prop, PropertyType type) {
FieldMapping field = FieldMapping.get(mapping, prop);
this.mappedProps.add(field);
this.propertiesByName.put(prop.getName(), prop);
this.fieldsByProperty.put(prop, field);
if (type != null)
this.typesByProperty.put(prop, type);
// !!! ADD HANDLING FOR INDEX ANNOTATIONS !!!
HIndex[] indexes = mapping.indexes();
if (indexes != null && indexes.length > 0) {
for (HIndex idx : indexes)
addIndex( new IndexMapping(this.table, field, idx), prop );
}
}
public void addIndex(IndexMapping index, PropertyDescriptor prop) {
List<IndexMapping> curIndexes = this.indexesByProperty.get(prop);
if (curIndexes == null) {
curIndexes = new ArrayList<IndexMapping>();
this.indexesByProperty.put(prop, curIndexes);
}
curIndexes.add(index);
}
public PropertyDescriptor getFieldProperty(String fieldname) {
for (FieldMapping mapping : this.mappedProps) {
if (mapping.matches(fieldname)) {
return mapping.getBeanProperty();
}
}
return null;
}
public List<FieldMapping> getMappedFields() { return this.mappedProps; }
public PropertyDescriptor getProperty(String propName) {
return this.propertiesByName.get(propName);
}
public FieldMapping getPropertyMapping(String propName) {
if (this.propertiesByName.get(propName) != null) {
return this.fieldsByProperty.get( this.propertiesByName.get(propName) );
}
return null;
}
public PropertyType getPropertyType(PropertyDescriptor prop) {
return this.typesByProperty.get(prop);
}
public List<IndexMapping> getPropertyIndexes(String propname) {
PropertyDescriptor prop = getProperty(propname);
if (prop != null)
return getPropertyIndexes(prop);
return null;
}
public List<IndexMapping> getPropertyIndexes(PropertyDescriptor prop) {
return this.indexesByProperty.get(prop);
}
public IndexMapping getFirstPropertyIndex(String propname) {
PropertyDescriptor prop = getProperty(propname);
if (prop != null)
return getFirstPropertyIndex(prop);
return null;
}
public IndexMapping getFirstPropertyIndex(PropertyDescriptor prop) {
List<IndexMapping> indexes = getPropertyIndexes(prop);
if (indexes != null && indexes.size() > 0)
return indexes.get(0);
return null;
}
public Map<PropertyDescriptor, List<IndexMapping>> getIndexesByProperty() {
return this.indexesByProperty;
}
/**
* Returns all index mappings present on this entity class
* @return
*/
public List<IndexMapping> getMappedIndexes() {
List<IndexMapping> indexes = new ArrayList<IndexMapping>(this.indexesByProperty.size());
for (List<IndexMapping> propIndexes : this.indexesByProperty.values())
indexes.addAll(propIndexes);
return indexes;
}
public boolean isGettable(String fieldname) {
PropertyDescriptor prop = getFieldProperty(fieldname);
return (prop != null && prop.getReadMethod() != null);
}
public boolean isSettable(String fieldname) {
PropertyDescriptor prop = getFieldProperty(fieldname);
return (prop != null && prop.getWriteMethod() != null);
}
public Collection<String> getColumnFamilyNames() {
if (this.columnFamilies == null) {
Set<String> names = new HashSet<String>();
for (FieldMapping mapping : this.mappedProps)
names.add(mapping.getFamily());
this.columnFamilies = names;
}
return this.columnFamilies;
}
private Set<String> columnFamilies = null;
}