package org.hivedb.hibernate.simplified; import org.hibernate.CallbackException; import org.hibernate.EmptyInterceptor; import org.hibernate.Interceptor; import org.hibernate.shards.util.InterceptorDecorator; import org.hibernate.type.Type; import org.hivedb.Hive; import org.hivedb.HiveLockableException; import org.hivedb.configuration.EntityConfig; import org.hivedb.configuration.EntityHiveConfig; import org.hivedb.hibernate.EntityResolver; import org.hivedb.hibernate.HiveIndexer; import org.hivedb.util.classgen.ReflectionTools; import org.hivedb.util.functional.Transform; import org.hivedb.util.functional.Unary; import java.io.Serializable; import java.util.Iterator; public class HiveInterceptorDecorator extends InterceptorDecorator implements Interceptor { private EntityHiveConfig hiveConfig; private HiveIndexer indexer; public HiveInterceptorDecorator(EntityHiveConfig hiveConfig, Hive hive) { this(EmptyInterceptor.INSTANCE, hiveConfig, hive); } public HiveInterceptorDecorator(Interceptor interceptor, EntityHiveConfig hiveConfig, Hive hive) { super(interceptor); this.hiveConfig = hiveConfig; this.indexer = new HiveIndexer(hive); } @Override public Boolean isTransient(Object entity) { Class<?> clazz = new EntityResolver(hiveConfig).resolveEntityInterface(entity.getClass()); if (clazz != null) return !indexer.exists(this.hiveConfig.getEntityConfig(clazz), entity); return super.isTransient(entity); } @SuppressWarnings("unchecked") private Class resolveEntityClass(Class clazz) { return ReflectionTools.whichIsImplemented( clazz, Transform.map(new Unary<EntityConfig, Class>() { public Class f(EntityConfig entityConfig) { return entityConfig.getRepresentedInterface(); } }, hiveConfig.getEntityConfigs())); } @Override public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { try { final Class<?> resolvedEntityClass = resolveEntityClass(entity.getClass()); if (resolvedEntityClass != null) indexer.delete(hiveConfig.getEntityConfig(entity.getClass()), entity); } catch (HiveLockableException e) { throw new CallbackException(e); } super.onDelete(entity, id, state, propertyNames, types); } @SuppressWarnings("unchecked") @Override public void postFlush(Iterator entities) throws CallbackException { while (entities.hasNext()) { Object entity = entities.next(); Class<?> resolvedClass = resolveEntityClass(entity.getClass()); if (resolvedClass != null) { final EntityConfig entityConfig = hiveConfig.getEntityConfig(resolvedClass); if (indexer.exists(entityConfig, entity)) updateIndexes(entity); else insertIndexes(entity); } } super.postFlush(entities); } private void updateIndexes(Object entity) { try { final Class<?> resolvedEntityClass = resolveEntityClass(entity.getClass()); if (resolvedEntityClass != null) { final EntityConfig entityConfig = hiveConfig.getEntityConfig(entity.getClass()); if (indexer.idExists(entityConfig, entityConfig.getId(entity))) indexer.updatePartitionDimensionIndexIfNeeded(hiveConfig.getEntityConfig(resolvedEntityClass), entity); indexer.update(entityConfig, entity); } } catch (HiveLockableException e) { throw new CallbackException(e); } } private void insertIndexes(Object entity) { try { final Class<?> resolvedEntityClass = resolveEntityClass(entity.getClass()); if (resolvedEntityClass != null) indexer.insert(hiveConfig.getEntityConfig(resolvedEntityClass), entity); } catch (HiveLockableException e) { throw new CallbackException(e); } } }