<commit_before>package org.openhds.controller.service.impl;

import java.sql.SQLException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.openhds.controller.exception.ConstraintViolations;
import org.openhds.controller.service.DeathService;
import org.openhds.controller.service.EntityService;
import org.openhds.controller.service.IndividualService;
import org.openhds.dao.service.GenericDao;
import org.openhds.domain.model.Death;
import org.openhds.domain.model.Individual;
import org.openhds.domain.model.Membership;
import org.openhds.domain.model.Relationship;
import org.openhds.domain.model.Residency;
import org.openhds.domain.model.SocialGroup;
import org.openhds.domain.service.SitePropertiesService;
import org.springframework.transaction.annotation.Transactional;

public class DeathServiceImpl implements DeathService {
	
	private static final int MILLISECONDS_IN_DAY = 86400000;
	private EntityService entityService;
	private GenericDao genericDao;
	private IndividualService individualService;
	private SitePropertiesService siteProperties;
	
	public DeathServiceImpl(GenericDao genericDao, IndividualService individualService, EntityService entityService, SitePropertiesService siteProperties) {
		this.genericDao = genericDao;
		this.individualService = individualService;
		this.entityService = entityService;
		this.siteProperties = siteProperties;
	}

	public Death evaluateDeath(Death entityItem) throws ConstraintViolations {
		
		if (!checkDuplicateIndividual(entityItem.getIndividual())) 
    		throw new ConstraintViolations("The Individual Id specified already exists.");	
		if (!checkHeadOfSocialGroup(entityItem.getIndividual())) 
    		throw new ConstraintViolations("The Individual specified is a Head of a Social Group. If you wish to create a Death event for this Individual, go to the Utility Menu and create a new Death event.");	
		
		return entityItem;
	}
		
	@Transactional(rollbackFor=Exception.class)
	public Death createDeath(Death entityItem) throws ConstraintViolations, SQLException {
		Calendar endDate = entityItem.getDeathDate();
		
		if (entityItem.getIndividual().getCurrentResidency() != null) {
			Residency residency = entityItem.getIndividual().getCurrentResidency();
			residency.setEndDate(endDate);
			residency.setEndType(siteProperties.getDeathCode());
			entityService.save(residency);
		}

		Long ageAtDeath = (endDate.getTimeInMillis() - entityItem.getIndividual().getDob().getTimeInMillis())/MILLISECONDS_IN_DAY;
		entityItem.setAgeAtDeath(ageAtDeath);
		
        //Gets the individual's memberships if any
        // Iterates through memberships and sets endType(DEATH) and endDate
        if (!entityItem.getIndividual().getAllMemberships().isEmpty()) {
            Set<Membership> memberships = (Set<Membership>) entityItem.getIndividual().getAllMemberships();
            for (Membership mem : memberships) {
            	if (mem.getEndType().equals(siteProperties.getNotApplicableCode())) {
	                mem.setEndDate(endDate);
	                mem.setEndType(siteProperties.getDeathCode());
	                entityService.save(mem);
            	}
            }
        }

        //Gets the individual's relationships if any
        // Iterates through the relationships and sets endType(DEATH) and endDate
         if (!entityItem.getIndividual().getAllRelationships1().isEmpty()) {
            Set<Relationship> relationships = (Set<Relationship>) entityItem.getIndividual().getAllRelationships1();
            Iterator<Relationship> it = relationships.iterator();
            while (it.hasNext()) {
                Relationship rel = it.next();
                if (rel.getEndType().equals(siteProperties.getNotApplicableCode())) {
	                rel.setEndDate(endDate);
	                rel.setEndType(siteProperties.getDeathCode());
	                entityService.save(rel);
                }
            }
        }
         
		 if (!entityItem.getIndividual().getAllRelationships2().isEmpty()) {
		     Set<Relationship> relationships = (Set<Relationship>) entityItem.getIndividual().getAllRelationships2();
		     Iterator<Relationship> it = relationships.iterator();
		     while (it.hasNext()) {
		         Relationship rel = it.next();
		         if (rel.getEndType().equals(siteProperties.getNotApplicableCode())) {
		             rel.setEndDate(endDate);
		             rel.setEndType(siteProperties.getDeathCode());
		             entityService.save(rel);
		         }
		     }
		 }
         
         entityService.create(entityItem);

         return entityItem;
	}

	@Transactional(rollbackFor=Exception.class)
	public void deleteDeath(Death entityItem) {
		
		if (entityItem.getIndividual().getCurrentResidency() != null && entityItem.getIndividual().getCurrentResidency().getEndType().equals(siteProperties.getDeathCode())) {
			entityItem.getIndividual().getCurrentResidency().setEndDate(null);
			entityItem.getIndividual().getCurrentResidency().setEndType(siteProperties.getNotApplicableCode());
		}

        if (!entityItem.getIndividual().getAllMemberships().isEmpty()) {
            Set<Membership> memberships = (Set<Membership>) entityItem.getIndividual().getAllMemberships();
            for (Membership mem : memberships) {
            	if (mem.getEndType().equals(siteProperties.getDeathCode())) {
	                mem.setEndDate(null);
	                mem.setEndType(siteProperties.getNotApplicableCode());
            	}
            }
        }

         if (!entityItem.getIndividual().getAllRelationships1().isEmpty()) {
            Set<Relationship> relationships = (Set<Relationship>) entityItem.getIndividual().getAllRelationships1();
            Iterator<Relationship> it = relationships.iterator();
            while (it.hasNext()) {<commit_msg>Added fix to prevent ConcurrencyException during DeathEvent<commit_after>package org.openhds.controller.service.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.openhds.controller.exception.ConstraintViolations;
import org.openhds.controller.service.DeathService;
import org.openhds.controller.service.EntityService;
import org.openhds.controller.service.IndividualService;
import org.openhds.dao.service.GenericDao;
import org.openhds.domain.model.Death;
import org.openhds.domain.model.Individual;
import org.openhds.domain.model.Membership;
import org.openhds.domain.model.Relationship;
import org.openhds.domain.model.Residency;
import org.openhds.domain.model.SocialGroup;
import org.openhds.domain.service.SitePropertiesService;
import org.springframework.transaction.annotation.Transactional;

public class DeathServiceImpl implements DeathService {
	
	private static final int MILLISECONDS_IN_DAY = 86400000;
	private EntityService entityService;
	private GenericDao genericDao;
	private IndividualService individualService;
	private SitePropertiesService siteProperties;
	
	public DeathServiceImpl(GenericDao genericDao, IndividualService individualService, EntityService entityService, SitePropertiesService siteProperties) {
		this.genericDao = genericDao;
		this.individualService = individualService;
		this.entityService = entityService;
		this.siteProperties = siteProperties;
	}

	public Death evaluateDeath(Death entityItem) throws ConstraintViolations {
		
		if (!checkDuplicateIndividual(entityItem.getIndividual())) 
    		throw new ConstraintViolations("The Individual Id specified already exists.");	
		if (!checkHeadOfSocialGroup(entityItem.getIndividual())) 
    		throw new ConstraintViolations("The Individual specified is a Head of a Social Group. If you wish to create a Death event for this Individual, go to the Utility Menu and create a new Death event.");	
		
		return entityItem;
	}
		
	@Transactional(rollbackFor=Exception.class)
	public Death createDeath(Death entityItem) throws ConstraintViolations, SQLException {
		Calendar endDate = entityItem.getDeathDate();
		
		if (entityItem.getIndividual().getCurrentResidency() != null) {
			Residency residency = entityItem.getIndividual().getCurrentResidency();
			residency.setEndDate(endDate);
			residency.setEndType(siteProperties.getDeathCode());
			entityService.save(residency);
		}

		Long ageAtDeath = (endDate.getTimeInMillis() - entityItem.getIndividual().getDob().getTimeInMillis())/MILLISECONDS_IN_DAY;
		entityItem.setAgeAtDeath(ageAtDeath);
		
        //Gets the individual's memberships if any
        // Iterates through memberships and sets endType(DEATH) and endDate
        if (!entityItem.getIndividual().getAllMemberships().isEmpty()) {
            Set<Membership> memberships = (Set<Membership>) entityItem.getIndividual().getAllMemberships();
            for (Membership mem : memberships) {
            	if (mem.getEndType().equals(siteProperties.getNotApplicableCode())) {
	                mem.setEndDate(endDate);
	                mem.setEndType(siteProperties.getDeathCode());
	                entityService.save(mem);
            	}
            }
        }

        //Gets the individual's relationships if any
        // Iterates through the relationships and sets endType(DEATH) and endDate
        List<Relationship> relationshipsToUpdate = new ArrayList<Relationship>();
        
         if (!entityItem.getIndividual().getAllRelationships1().isEmpty()) {
            Set<Relationship> relationships = (Set<Relationship>) entityItem.getIndividual().getAllRelationships1();
            Iterator<Relationship> it = relationships.iterator();
            while (it.hasNext()) {
                Relationship rel = it.next();
                if (rel.getEndType().equals(siteProperties.getNotApplicableCode())) {
	                rel.setEndDate(endDate);
	                rel.setEndType(siteProperties.getDeathCode());
//	                entityService.save(rel);
	                relationshipsToUpdate.add(rel);
                }
            }
         }
                 
		 if (!entityItem.getIndividual().getAllRelationships2().isEmpty()) {
		     Set<Relationship> relationships = (Set<Relationship>) entityItem.getIndividual().getAllRelationships2();
		     Iterator<Relationship> it = relationships.iterator();
		     while (it.hasNext()) {
		         Relationship rel = it.next();
		         if (rel.getEndType().equals(siteProperties.getNotApplicableCode())) {
		             rel.setEndDate(endDate);
		             rel.setEndType(siteProperties.getDeathCode());
//		             entityService.save(rel);
		             relationshipsToUpdate.add(rel);
		         }
		     }
		 }
		 
         for(Relationship rel : relationshipsToUpdate){
        	 entityService.save(rel);
         }		 
         
         entityService.create(entityItem);

         return entityItem;
	}

	@Transactional(rollbackFor=Exception.class)
	public void deleteDeath(Death entityItem) {
		
		if (entityItem.getIndividual().getCurrentResidency() != null && entityItem.getIndividual().getCurrentResidency().getEndType().equals(siteProperties.getDeathCode())) {
			entityItem.getIndividual().getCurrentResidency().setEndDate(null);
			entityItem.getIndividual().getCurrentResidency().setEndType(siteProperties.getNotApplicableCode());
		}

        if (!entityItem.getIndividual().getAllMemberships().isEmpty()) {
            Set<Membership> memberships = (Set<Membership>) entityItem.getIndividual().getAllMemberships();
            for (Membership mem : memberships) {
            	if (mem.getEndType().equals(siteProperties.getDeathCode())) {
	                mem.setEndDate(null);
	                mem.setEndType(siteProperties.getNotApplicableCode());
            	}
            }
        }

         if (!entityItem.getIndividual().getAllRelationships1().isEmpty()) {
            Set<Relationship> relationships = (Set<Relationship>) entityItem.getIndividual().getAllRelationships1();
            Iterator<Relationship> it = relationships.iterator();
            while (it.hasNext()) {
{'fraction_non_alphanumeric': 0.10376499793131982, 'fraction_numerical': 0.002316921803889119, 'mean_word_length': 3.567649281934996, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2019251', 'n_tokens_mistral': 3516, 'n_tokens_neox': 3119, 'n_words': 578}