package org.intermine.dataloader;

/*
 * Copyright (C) 2002-2005 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */

import java.util.Collections;
import java.util.Iterator;
import java.util.Set;

import org.intermine.objectstore.ObjectStore;
import org.intermine.objectstore.ObjectStoreException;
import org.intermine.model.InterMineObject;
import org.intermine.util.DynamicUtil;

/**
 * Class providing EquivalentObjectFetcher functionality that makes use of hints to improve
 * performance.
 *
 * @author Matthew Wakeling
 */
public class HintingFetcher implements EquivalentObjectFetcher
{
    ObjectStore os;
    EquivalentObjectHints hints;
    EquivalentObjectFetcher fetcher;

    /**
     * Constructor
     *
     * @param os the ObjectStore containing the equivalent objects
     * @param fetcher another EquivalentObjectFetcher
     */
    public HintingFetcher(ObjectStore os, EquivalentObjectFetcher fetcher) {
        this.os = os;
        this.hints = new EquivalentObjectHints(os);
        this.fetcher = fetcher;
    }

    /**
     * @see EquivalentObjectFetcher#queryEquivalentObjects
     */
    public Set queryEquivalentObjects(InterMineObject obj, Source source)
        throws ObjectStoreException {
        if (hints.databaseEmpty()) {
            return Collections.EMPTY_SET;
        }
        Iterator classIter = DynamicUtil.decomposeClass(obj.getClass()).iterator();
        while (classIter.hasNext()) {
            Class clazz = (Class) classIter.next();
            if (os.getModel().hasClassDescriptor(clazz.getName())) {
                if (hints.classNotExists(clazz)) {
                    return Collections.EMPTY_SET;
                }
            }
        }
        return fetcher.queryEquivalentObjects(obj, source);
    }
}

@@ -507,16 +507,63 @@
 eption;%0A
+import org.intermine.metadata.ClassDescriptor;%0A
 import o
@@ -1582,71 +1582,175 @@
     
-Iterator classIter = DynamicUtil.decomposeClass(obj.getClass())
+boolean allPkClassesEmpty = true;%0A        Set classDescriptors = os.getModel().getClassDescriptorsForClass(obj.getClass());%0A        Iterator cldIter = classDescriptors
 .ite
@@ -1775,19 +1775,17 @@
 hile (cl
-ass
+d
 Iter.has
@@ -1794,51 +1794,88 @@
 xt()
-) %7B%0A            Class clazz = (Class
+ && allPkClassesEmpty) %7B%0A            ClassDescriptor cld = (ClassDescriptor
 ) cl
-ass
+d
 Iter
@@ -1899,60 +1899,109 @@
     
-if (os.getModel().hasClassDescriptor(clazz.getName()
+Set primaryKeys = DataLoaderHelper.getPrimaryKeys(cld, source);%0A            if (!primaryKeys.isEmpty(
 )) %7B
@@ -2017,24 +2017,25 @@
         if (
+!
 hints.classN
@@ -2049,11 +2049,19 @@
 s(cl
-azz
+d.getType()
 )) %7B
@@ -2085,36 +2085,33 @@
     
-return Collections.EMPTY_SET
+allPkClassesEmpty = false
 ;%0A  
@@ -2142,32 +2142,117 @@
     %7D%0A        %7D%0A
+        if (allPkClassesEmpty) %7B%0A            return Collections.EMPTY_SET;%0A        %7D%0A
         return f

Fix bug where hints falsly stated that database was empty for a particular class. Now looks at all superclasses and checks that the database is empty for each of these for which a primary key is to be used.