package org.hivedb.serialization;
import org.hibernate.HibernateException;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.property.Getter;
import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.Setter;
import org.hivedb.annotations.AnnotationHelper;
import org.hivedb.annotations.Index;
import org.hivedb.util.classgen.ReflectionTools;
import org.hivedb.util.functional.Atom;
import org.hivedb.util.functional.Transform;
import org.hivedb.util.functional.Unary;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
/***
* When persisting a class as an XML blob, we may still wish index the Ids of one of it's properties
* that is a one-to-many collection of instances.
* This PropertyAccessor allows us to declare a collection of instances as a bag of
* primitives in the Hibernate declaration, when in reality the blob class has a collection of
* instances. ExtractPrimitiveAccessor extracts the Id from each instance of the collection and
* returns the collection of Ids, which Hibernate in turn persists in an association table. See tests.
* @author andylikuski
*
*/
public class ExtractPrimitiveAccessor implements PropertyAccessor {
public Getter getGetter(Class clazz, final String propertyName)
throws PropertyNotFoundException {
Class collectionType = ReflectionTools.getCollectionItemType(clazz, propertyName);
final Method indexMethod = Atom.getFirstOrThrow(AnnotationHelper.getAllMethodsWithAnnotation(collectionType, Index.class));
return new Getter() {
public Object get(Object instance) throws HibernateException {
Collection<Object> collection = (Collection<Object>) ReflectionTools.invokeGetter(instance, propertyName);
return Transform.map(new Unary<Object, Object>() {
public Object f(Object item) {
try {
return indexMethod.invoke(item, new Object[] {});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, collection != null ? collection : Collections.emptyList());
}
public Object getForInsert(Object arg0, Map arg1,
SessionImplementor arg2) throws HibernateException {
return null;
}
public Method getMethod() {
return null;
}
public String getMethodName() {
// TODO Auto-generated method stub
return null;
}
public Class getReturnType() {
return indexMethod.getReturnType();
}
};
}
public Setter getSetter(Class clazz, final String propertyName)
throws PropertyNotFoundException {
return setter;
}
private static Setter setter = new Setter() {
public Method getMethod() {
return null;
}
public String getMethodName() {
return null;
}
public void set(Object target, Object value, SessionFactoryImplementor sessionFactory)
throws HibernateException {
}
};
}