<commit_before>package gov.nih.nci.nbia.dynamicsearch;

import gov.nih.nci.nbia.dao.AbstractDAO;
import gov.nih.nci.nbia.dto.QcSearchResultDTO;
import gov.nih.nci.nbia.dto.StudyNumberDTO;
import gov.nih.nci.nbia.dynamicsearch.criteria.CriteriaFactory;
import gov.nih.nci.nbia.dynamicsearch.criteria.CriteriaForAuthorizedSiteData;
import gov.nih.nci.nbia.internaldomain.GeneralSeries;
import gov.nih.nci.nbia.internaldomain.Patient;
import gov.nih.nci.nbia.lookup.StudyNumberMap;
import gov.nih.nci.nbia.qctool.VisibilityStatus;
import gov.nih.nci.nbia.search.LocalNode;
import gov.nih.nci.nbia.util.SiteData;
import gov.nih.nci.nbia.util.StringUtil;
import gov.nih.nci.nbia.xmlobject.Element;
import gov.nih.nci.ncia.search.PatientSearchResult;
import gov.nih.nci.ncia.search.PatientSearchResultImpl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

//the name of this object should reflect that the target of the
//query is always a Patient.
public class QueryHandlerImpl extends AbstractDAO 
                              implements QueryHandler {
	private List<DynamicSearchCriteria> searchCriteria = new ArrayList<DynamicSearchCriteria>();
	private List<DynamicSearchCriteria> originalCriteria = null;
	private List<Element> elementTree;
	private String currentNode ="";
	private String statementRelation = "";
	private Map<String, String> sourceToAliasMap = new HashMap<String, String>();
	private List<PatientSearchResult> patients;
	private List<SiteData> authorizedSiteData;
	private List<String> seriesSecurityGroups;

	private StudyNumberMap studyNumberMap = null;

	private static final String LOGICAL_OPERATOR_AND = "AND";
	private static final String LOGICAL_OPERATOR_OR = "OR";

	public void setStudyNumberMap(StudyNumberMap theStudyNumberMap) {
		this.studyNumberMap = theStudyNumberMap;
	}

	@Transactional(propagation=Propagation.REQUIRED) 	
	public void query() throws DataAccessException {
		DetachedCriteria criteria = null;
		try
		{
	        criteria = DetachedCriteria.forClass(Patient.class);

			ProjectionList projectionList = Projections.projectionList();
            projectionList.add(Projections.property("id"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(2).getAlias())+".id"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".id"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(0).getAlias())+".project"));
            projectionList.add(Projections.property("patientId"));
            criteria.setProjection(Projections.distinct(projectionList));

			criteria = addAllJoinKeys(criteria);
			criteria = addAllRestriction(criteria, searchCriteria);
			//add user authorized site name and collection
			CriteriaForAuthorizedSiteData casd = new CriteriaForAuthorizedSiteData();
			casd.setAuthorizedSiteData(generateAlias(elementTree.get(0).getAlias()),
					                   criteria,
					                   authorizedSiteData);
			//add this for IDRI security group
			casd.setSeriesSecurityGroups(generateAlias(elementTree.get(3).getAlias()),
					                     criteria,
					                     seriesSecurityGroups);
			criteria.addOrder(Order.asc("patientId"));
			List<Object[]> p = executeQuery(criteria);

			List<PatientSearchResult> pList = this.createPatientDTOBasedUponResultSet(p);
			this.setPatients(pList);


		}
		catch(Exception ex) {
			throw new RuntimeException(ex);
		}
		finally
		{
			criteria = null;
			removeSeriesVisibilityCriteria();
		}
	}
	@Transactional(propagation=Propagation.REQUIRED) 	
	public List<QcSearchResultDTO> querySeries() throws DataAccessException {
		DetachedCriteria criteria = null;
		List<QcSearchResultDTO> searchResultDtos = new ArrayList<QcSearchResultDTO>();
		try
		{
	        criteria = DetachedCriteria.forClass(Patient.class);

			ProjectionList projectionList = Projections.projectionList();
            projectionList.add(Projections.property(generateAlias(elementTree.get(0).getAlias())+".project"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".site"));
            projectionList.add(Projections.property("patientId"));
			projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".studyInstanceUID"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".seriesInstanceUID"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".visibility"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".maxSubmissionTimestamp"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".modality"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".seriesDesc"));            
            criteria.setProjection(Projections.distinct(projectionList));

			criteria = addAllJoinKeys(criteria);
			criteria = addAllRestriction(criteria, searchCriteria);
			//add user authorized site name and collection
			CriteriaForAuthorizedSiteData casd = new CriteriaForAuthorizedSiteData();
			casd.setAuthorizedSiteData(generateAlias(elementTree.get(0).getAlias()),
					                   criteria,
					                   authorizedSiteData);
			//add this for IDRI security group
			casd.setSeriesSecurityGroups(generateAlias(elementTree.get(3).getAlias()),
					                     criteria,
					                     seriesSecurityGroups);

			List<Object[]> searchResults = executeQuery(criteria);

			for (Object[] row : searchResults) {
				String collection = (String) row[0];
				String site = (String) row[1];
				String patient = (String) row[2];
				String study = (String) row[3];
				String series = (String) row[4];
				String visibilitySt = (String) row[5];
				Timestamp submissionDate = (Timestamp) row[6];
				String modality = (String) row[7];
				String seriesDesc = (String) row[8];

				QcSearchResultDTO qcSrDTO = new QcSearchResultDTO(collection,
						                                          site,
						                                          patient,
						                                          study,
						                                          series,
						                                          new Date(submissionDate.getTime()),
						                                          visibilitySt, modality, seriesDesc);
				searchResultDtos.add(qcSrDTO);
			}

		}
		catch(Exception ex) {
			throw new RuntimeException(ex);
		}
		finally
		{
			criteria = null;
			removeSeriesVisibilityCriteria();
		}
		return searchResultDtos;
	}
	/**
	 * This method prepares all necessary conditions for Query builder method.
	 * This method must be called before calling buildQuery().
	 */
	public void setQueryCriteria(List<DynamicSearchCriteria> criteria,
			                     String stateRelation, List<SiteData> aData,
			                     List<String> securityGroups) 
	{
		try {
			TableRelationships ro = new TableRelationships();
			elementTree = ro.getRelationTree();
			createMapKeys();
			//add visibility = 1 in generalSeries level
			criteria.add(createSeriesVisibilityCriteria(Arrays.asList("1")));
	
			searchCriteria = ro.sortTableName(criteria);
			//reset currentNode
			originalCriteria = criteria;
			//what happens here if criteria is zero length?
			currentNode = elementTree.get(1).getAlias();
			this.statementRelation = stateRelation;
			this.authorizedSiteData = aData;
			this.seriesSecurityGroups = securityGroups;
		}
		catch(Exception ex) {
			throw new RuntimeException(ex);
		}
	}
	/**
	 * This method prepares all necessary conditions for Query builder method.<commit_msg>Added debug stmt for NBIA-444 <commit_after>package gov.nih.nci.nbia.dynamicsearch;

import gov.nih.nci.nbia.dao.AbstractDAO;
import gov.nih.nci.nbia.dto.QcSearchResultDTO;
import gov.nih.nci.nbia.dto.StudyNumberDTO;
import gov.nih.nci.nbia.dynamicsearch.criteria.CriteriaFactory;
import gov.nih.nci.nbia.dynamicsearch.criteria.CriteriaForAuthorizedSiteData;
import gov.nih.nci.nbia.internaldomain.GeneralSeries;
import gov.nih.nci.nbia.internaldomain.Patient;
import gov.nih.nci.nbia.lookup.StudyNumberMap;
import gov.nih.nci.nbia.qctool.VisibilityStatus;
import gov.nih.nci.nbia.search.LocalNode;
import gov.nih.nci.nbia.util.SiteData;
import gov.nih.nci.nbia.util.StringUtil;
import gov.nih.nci.nbia.xmlobject.Element;
import gov.nih.nci.ncia.search.PatientSearchResult;
import gov.nih.nci.ncia.search.PatientSearchResultImpl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

//the name of this object should reflect that the target of the
//query is always a Patient.
public class QueryHandlerImpl extends AbstractDAO 
                              implements QueryHandler {
	private List<DynamicSearchCriteria> searchCriteria = new ArrayList<DynamicSearchCriteria>();
	private List<DynamicSearchCriteria> originalCriteria = null;
	private List<Element> elementTree;
	private String currentNode ="";
	private String statementRelation = "";
	private Map<String, String> sourceToAliasMap = new HashMap<String, String>();
	private List<PatientSearchResult> patients;
	private List<SiteData> authorizedSiteData;
	private List<String> seriesSecurityGroups;

	private StudyNumberMap studyNumberMap = null;

	private static final String LOGICAL_OPERATOR_AND = "AND";
	private static final String LOGICAL_OPERATOR_OR = "OR";

	public void setStudyNumberMap(StudyNumberMap theStudyNumberMap) {
		this.studyNumberMap = theStudyNumberMap;
	}

	@Transactional(propagation=Propagation.REQUIRED) 	
	public void query() throws DataAccessException {
		DetachedCriteria criteria = null;
		try
		{
	        criteria = DetachedCriteria.forClass(Patient.class);

			ProjectionList projectionList = Projections.projectionList();
            projectionList.add(Projections.property("id"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(2).getAlias())+".id"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".id"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(0).getAlias())+".project"));
            projectionList.add(Projections.property("patientId"));
            criteria.setProjection(Projections.distinct(projectionList));

			criteria = addAllJoinKeys(criteria);
			criteria = addAllRestriction(criteria, searchCriteria);
			//add user authorized site name and collection
			CriteriaForAuthorizedSiteData casd = new CriteriaForAuthorizedSiteData();
			casd.setAuthorizedSiteData(generateAlias(elementTree.get(0).getAlias()),
					                   criteria,
					                   authorizedSiteData);
			//add this for IDRI security group
			casd.setSeriesSecurityGroups(generateAlias(elementTree.get(3).getAlias()),
					                     criteria,
					                     seriesSecurityGroups);
			criteria.addOrder(Order.asc("patientId"));
			List<Object[]> p = executeQuery(criteria);

			List<PatientSearchResult> pList = this.createPatientDTOBasedUponResultSet(p);
			this.setPatients(pList);


		}
		catch(Exception ex) {
			throw new RuntimeException(ex);
		}
		finally
		{
			criteria = null;
			removeSeriesVisibilityCriteria();
		}
	}
	@Transactional(propagation=Propagation.REQUIRED) 	
	public List<QcSearchResultDTO> querySeries() throws DataAccessException {
		DetachedCriteria criteria = null;
		List<QcSearchResultDTO> searchResultDtos = new ArrayList<QcSearchResultDTO>();
		try
		{
	        criteria = DetachedCriteria.forClass(Patient.class);

			ProjectionList projectionList = Projections.projectionList();
            projectionList.add(Projections.property(generateAlias(elementTree.get(0).getAlias())+".project"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".site"));
            projectionList.add(Projections.property("patientId"));
			projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".studyInstanceUID"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".seriesInstanceUID"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".visibility"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".maxSubmissionTimestamp"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".modality"));
            projectionList.add(Projections.property(generateAlias(elementTree.get(3).getAlias())+".seriesDesc"));            
            criteria.setProjection(Projections.distinct(projectionList));

			criteria = addAllJoinKeys(criteria);
			criteria = addAllRestriction(criteria, searchCriteria);
			//add user authorized site name and collection
			CriteriaForAuthorizedSiteData casd = new CriteriaForAuthorizedSiteData();
			casd.setAuthorizedSiteData(generateAlias(elementTree.get(0).getAlias()),
					                   criteria,
					                   authorizedSiteData);
			//add this for IDRI security group
			casd.setSeriesSecurityGroups(generateAlias(elementTree.get(3).getAlias()),
					                     criteria,
					                     seriesSecurityGroups);

			List<Object[]> searchResults = executeQuery(criteria);
			if (searchResults != null) { 
				System.out.println("searchResults " + searchResults.size());
				for (Object[] row : searchResults) {
					String collection = (String) row[0];
					String site = (String) row[1];
					String patient = (String) row[2];
					String study = (String) row[3];
					String series = (String) row[4];
					String visibilitySt = (String) row[5];
					Timestamp submissionDate = (Timestamp) row[6];
					String modality = (String) row[7];
					String seriesDesc = (String) row[8];
	
					QcSearchResultDTO qcSrDTO = new QcSearchResultDTO(collection,
							                                          site,
							                                          patient,
							                                          study,
							                                          series,
							                                          new Date(submissionDate.getTime()),
							                                          visibilitySt, modality, seriesDesc);
					searchResultDtos.add(qcSrDTO);
				}
			}

		}
		catch(Exception ex) {
			throw new RuntimeException(ex);
		}
		finally
		{
			criteria = null;
			removeSeriesVisibilityCriteria();
		}
		return searchResultDtos;
	}
	/**
	 * This method prepares all necessary conditions for Query builder method.
	 * This method must be called before calling buildQuery().
	 */
	public void setQueryCriteria(List<DynamicSearchCriteria> criteria,
			                     String stateRelation, List<SiteData> aData,
			                     List<String> securityGroups) 
	{
		try {
			TableRelationships ro = new TableRelationships();
			elementTree = ro.getRelationTree();
			createMapKeys();
			//add visibility = 1 in generalSeries level
			criteria.add(createSeriesVisibilityCriteria(Arrays.asList("Visible")));
	
			searchCriteria = ro.sortTableName(criteria);
			//reset currentNode
			originalCriteria = criteria;
			//what happens here if criteria is zero length?
			currentNode = elementTree.get(1).getAlias();
			this.statementRelation = stateRelation;
			this.authorizedSiteData = aData;
			this.seriesSecurityGroups = securityGroups;
		}
		catch(Exception ex) {
			throw new RuntimeException(ex);
		}
	}
	/**
	 * This method prepares all necessary conditions for Query builder method.
{'fraction_non_alphanumeric': 0.10335735630163473, 'fraction_numerical': 0.0032811859143376107, 'mean_word_length': 3.62296858071506, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6024126', 'n_tokens_mistral': 5216, 'n_tokens_neox': 4649, 'n_words': 851}