package net.straininfo2.grs.idloader.db;

import net.straininfo2.grs.idloader.bioproject.domain.AdminBioProject;
import net.straininfo2.grs.idloader.bioproject.domain.BioProject;
import net.straininfo2.grs.idloader.bioproject.domain.SubmissionBioProject;
import net.straininfo2.grs.idloader.bioproject.xmlparsing.DomainHandler;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

public class BioProjectLoader implements DomainHandler {

    /*
    Manages its own running session, that way can implement committing the transaction
     every x elements.
     */
    // TODO: ADD CLEANUP OF ORGANISM ONE-TO-ONEs (elsewhere)
    /*
    OrganismMorphology
    OrganismEnvironment
    OrganismPhenotype
    OrganismSample
     */
    @Autowired
    SessionFactory sessionFactory;

    private Session currentSession;

    private int count = 0;

    private final static Logger logger = LoggerFactory.getLogger(DomainHandler.class);

    public BioProjectLoader() {
    }

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    private void checkTransaction() {
        count++;
        if (currentSession == null) {
            currentSession = sessionFactory.openSession();
            currentSession.beginTransaction();
        }
        if (count % 1000 == 0) {
            currentSession.getTransaction().commit();
            currentSession.close();
            currentSession = sessionFactory.openSession();
            currentSession.beginTransaction();
        }
    }

    @Override
    public void processBioProject(BioProject project) {
        checkTransaction();
        logger.info("Saving project with ID {}", project.getProjectId());
        currentSession.merge(project);
    }

    @SuppressWarnings("unchecked")
    private BioProject loadCurrent(long id) {
        return (BioProject)currentSession.get(BioProject.class, id);
    }

    @Override
    public void processAdminBioProject(AdminBioProject project) {
        checkTransaction();
        logger.info("Saving project with ID {}", project.getProjectId());
        BioProject current = loadCurrent(project.getProjectId());
        if (current != null && !(current instanceof AdminBioProject)) {
            // sometimes projects change type, replace the entry
            currentSession.delete(current);
            currentSession.persist(project);
        }
        else{
            currentSession.merge(project);
        }
    }

    @Override
    public void processSubmissionBioProject(SubmissionBioProject project) {
        checkTransaction();
        logger.info("Saving project with ID {}", project.getProjectId());
        BioProject current = loadCurrent(project.getProjectId());
        if (current != null && !(current instanceof SubmissionBioProject)) {
            currentSession.delete(current);
            currentSession.persist(project);
        }
        else{
            currentSession.merge(project);
        }
    }

    @Override
    public void endParsing() {
        currentSession.getTransaction().commit();
        currentSession.close();
    }
}

@@ -1834,267 +1834,670 @@
    @
-Override%0A    public void processBioProject(BioProject project) %7B%0A        checkTransaction();
+SuppressWarnings(%22unchecked%22)%0A    private BioProject loadCurrent(long id) %7B%0A        return (BioProject)currentSession.get(BioProject.class, id);%0A    %7D%0A%0A    /**%0A     * Copy mappings, if any, from the old project to the new one. This%0A     * method is null-safe.
 %0A     
+*%0A
    
-logger.info(%22Saving project with ID %7B%7D%22, project.getProjectId());%0A        currentSession.merge(project);%0A    %7D%0A%0A    @SuppressWarnings(%22unchecked%22)%0A    private
+  * @param old project to copy mappings from%0A     * @param updated recipient of mappings%0A     */%0A    private static void copyMappings(BioProject old, BioProject updated) %7B%0A        if (old != null && updated != null) %7B%0A            updated.setMappings(old.getMappings());%0A        %7D%0A    %7D%0A%0A    @Override%0A    public void processBioProject(BioProject project) %7B%0A        checkTransaction();%0A       
  Bio
@@ -2495,32 +2495,42 @@
       BioProject
+ current =
  loadCurrent(lon
@@ -2530,85 +2530,183 @@
 ent(
-long id) %7B%0A        return (BioProject)currentSession.get(BioProject.class, id
+project.getProjectId());%0A        copyMappings(current, project);%0A        logger.info(%22Saving project with ID %7B%7D%22, project.getProjectId());%0A        currentSession.merge(project
 );%0A 
@@ -2951,32 +2951,72 @@
 etProjectId());%0A
+        copyMappings(current, project);%0A
         if (curr
@@ -3559,32 +3559,72 @@
 etProjectId());%0A
+        copyMappings(current, project);%0A
         if (curr

Copy mappings before merging a bioproject