/* * $Id$ * * Copyright 2009 Glencoe Software, Inc. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package ome.tools.hibernate; import java.util.HashMap; import java.util.Map; import ome.conditions.ApiUsageException; import ome.model.IEnum; import ome.model.IObject; import ome.util.Filterable; import org.hibernate.Query; import org.hibernate.Session; /** * {@link UpdateFilter} subclass specialized for use with the * {@link Session#save(Object)} (as opposed to {@link Session#merge(Object)}) * method. This is primarily of use during import when all objects are either * unloaded, enums, or newly created instances. * * @since Beta4.1 */ public class ReloadFilter extends UpdateFilter { private final Session session; /** * Cache of all the enumerations which have been looked up via the session * in {@link #filter(String, Object)}. */ private final Map<Class, Map<String, IEnum>> enumsMap = new HashMap<Class, Map<String, IEnum>>(); public ReloadFilter(Session s) { this.session = s; } public Filterable filter(String fieldId, Filterable f) { // If the session already has this object load then we can move on. if (session.contains(f)) { return f; } if (f instanceof IObject) { // For the moment we are only worrying with IObjects. // The logic for handling Details, and other Filterable objects // should be the default. IObject o = (IObject) f; // If the object is unloaded, then we load it. if (!o.isLoaded()) { return (IObject) session.get(o.getClass(), o.getId()); } // If the object is an enum, then we try to match based on value. if (f instanceof IEnum) { IEnum e = (IEnum) f; String val = e.getValue(); // First, heck if in map. Map<String, IEnum> enums = enumsMap.get(f.getClass()); if (enums != null) { IEnum enu = enums.get(val); if (enu != null) { return enu; } } // We haven't seen this enum yet. Try to load it, and if found // put it in enumsMap Query q = session.createQuery(String.format( "select e from %s e where e.value = :val", f.getClass() .getName())); q.setString("val", val); IEnum existing = (IEnum) q.uniqueResult(); if (existing != null) { enums = enumsMap.get(f.getClass()); if (enums == null) { enums = new HashMap<String, IEnum>(); enumsMap.put(f.getClass(), enums); } enums.put(val, existing); return existing; } } // Finally, if we've reached here, then this object is not an enum // and not unloaded. If it has an id, that means a user *might* be // trying to make an UPDATE, but these operations assume INSERT // only. if (o.getId() != null) { throw new ApiUsageException( "INSERTs only! Pass only new objects, enums, or " + "unloaded objects to this method."); } } return super.filter(fieldId, f); } }