package javango.contrib.hibernate;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Configuration;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Value;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import javango.contrib.i18n.I18NProvider;
import javango.db.Manager;
import javango.db.ManagerException;
import javango.db.QuerySet;
public class HibernateManager<T> implements Manager<T> {
private final HibernateUtil hibernateUtil;
private final Class<? extends T> model;
@Inject
public HibernateManager(HibernateUtil hibernateUtil, @Assisted Class<? extends T> model) {
super();
this.hibernateUtil = hibernateUtil;
this.model = model;
}
public QuerySet<T> all() throws ManagerException {
try {
return new HibernateQuerySet<T>(hibernateUtil, model);
} catch (Exception e) {
throw new ManagerException(e);
}
}
public void delete(T object) throws ManagerException {
try {
hibernateUtil.getSession().delete(object);
} catch (HibernateException e) {
throw new ManagerException(e);
}
}
public QuerySet<T> filter(Map<String, Object> params) throws ManagerException {
return all().filter(params);
}
public QuerySet<T> filter(Object params) throws ManagerException {
return all().filter(params);
}
public QuerySet<T> filter(String property, Object value) throws ManagerException {
return all().filter(property, value);
}
public QuerySet<T> filterByProperty(String propertyA, String propertyB) throws ManagerException {
return all().filterByProperty(propertyA, propertyB);
}
@SuppressWarnings("unchecked")
public T get(Serializable key) throws ManagerException {
if (key == null) return null;
Class<?>[] keyClass = getPkClass();
if (keyClass.length != 1) {
throw new ManagerException("get(pk) not supported for composite keyed models");
}
if (key.getClass().equals(keyClass[0])) {
return (T) hibernateUtil.getSession().get(model, key);
}
// if (log.isDebugEnabled()) log.debug("Trying to convert input to type " + keyClass[0]);
Object o = new ConvertUtilsBean().convert(key.toString(), keyClass[0]);
return (T)hibernateUtil.getSession().get(model, (Serializable)o);
}
public T save(T object) throws ManagerException {
try {
hibernateUtil.getSession().saveOrUpdate(object);
} catch (HibernateException e) {
throw new ManagerException(e);
}
return object;
}
public T create(T object) throws ManagerException {
try {
hibernateUtil.getSession().save(object);
} catch (HibernateException e) {
throw new ManagerException(e);
}
return object;
}
public Serializable getPk(T object) throws ManagerException {
try {
return hibernateUtil.getSession().getIdentifier(object);
} catch (HibernateException e) {
// TODO Throw something cool here and elsewhere...
throw new ManagerException(e);
}
}
/**
* Returns a the keys Class[]
* @return
* @throws DaoException
*/
public Class[] getPkClass() throws ManagerException {
Configuration cfg = hibernateUtil.getConfiguration();
PersistentClass pclass = cfg.getClassMapping(model.getName());
if (pclass == null) {
throw new ManagerException("Unable to find class : "+ model.toString());
}
Property componentProperty = pclass.getIdentifierProperty();
if (componentProperty == null) {
Component component = pclass.getIdentifierMapper();
if (component == null) {
throw new ManagerException("Unable to get pk mapping");
}
// if (log.isDebugEnabled()) log.debug(String.format("Found %d keys for model %s", component.getPropertySpan(), model.getName()));
Class<?>[] classArray = new Class[component.getColumnSpan()];
Iterator<Property> ite = component.getPropertyIterator();
int i = 0;
while (ite.hasNext()) {
Property p = ite.next();
// if (log.isDebugEnabled()) log.debug("property name: " + p.getName());
classArray[i++] = p.getType().getReturnedClass();
}
return classArray;
} else {
Value value = componentProperty.getValue();
if (value == null)
throw new ManagerException("Component value is null");
else {
// if (log.isDebugEnabled()) log.debug(String.format("Found simple key for model %s '%s'", model.getName(), value.getType().getReturnedClass()));
return new Class[] { value.getType().getReturnedClass() };
}
}
}
/**
* Returns a the keys Class[]
* @return
* @throws DaoException
*/
public String getPkProperty() throws ManagerException {
Configuration cfg = hibernateUtil.getConfiguration();
PersistentClass pclass = cfg.getClassMapping(model.getName());
if (pclass == null) {
throw new ManagerException("Unable to find class : "
+ model.toString());
}
Property componentProperty = pclass.getIdentifierProperty();
if (componentProperty == null) {
throw new UnsupportedOperationException("Multiple primary keys not supported");
// Component component = pclass.getIdentifierMapper();
// if (component == null) {
// throw new DaoException("Unable to get pk mapping");
// }
// if (log.isDebugEnabled()) log.debug(String.format("Found %d keys for model %s", component.getPropertySpan(), modelClass.getName()));
//
// Class<?>[] classArray = new Class[component.getColumnSpan()];
// Iterator<Property> ite = component.getPropertyIterator();
// int i = 0;
// while (ite.hasNext()) {
// Property p = ite.next();
// if (log.isDebugEnabled()) log.debug("property name: " + p.getName());
// classArray[i++] = p.getType().getReturnedClass();
// }
// return classArray;
} else {
return componentProperty.getName();
}
}
}