<commit_before>package edu.duke.cabig.c3pr.dao;

import gov.nih.nci.cabig.ctms.dao.AbstractDomainObjectDao;
import gov.nih.nci.cabig.ctms.domain.DomainObject;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

/**
 * Abstract BaseDao implementing BaseDao. Provides convenient methods for saving a base Dao
 * 
 * @author Priyatam
 */
public abstract class C3PRBaseDao<T extends DomainObject> extends AbstractDomainObjectDao<T> {

    private static Log log = LogFactory.getLog(C3PRBaseDao.class);

    /**
     * Get Object by Id (based on domain class) with eager fetch of a single association
     * 
     * @param id
     *                object id
     * @param isEager
     *                true if eager fetch is needed
     * @param associationPath
     *                the association 'name' needed to be loaded
     * @return loaded persistent object
     */
    public T getById(int id, boolean isEager, String associationPath) {
        if (isEager) {
            Criterion idCr = Restrictions.eq("id", id);
            Criteria criteria = getSession().createCriteria(domainClass()).setFetchMode(
                            associationPath, FetchMode.JOIN).add(idCr);
            return (T) criteria.list().get(0);
        }
        return getById(id);
    }

    /*
     * Must override in subclass to return the domain class reference in the dao
     */
    public abstract Class<T> domainClass();

    /*
     * Saves a domain object
     */
    public void save(DomainObject domainObject) {
        getHibernateTemplate().saveOrUpdate(domainObject);
        postProcessSave();
    }

    /*
     * Saves a domain object
     */
    public void merge(DomainObject domainObject) {
        getHibernateTemplate().merge(domainObject);
        postProcessSave();
    }

    /**
     * To be implemented by subclasses for custom extension of save
     */
    protected void postProcessSave() {
        // default is empty implementation
    }

    /**
     * A variation of {@link #findBySubname} that does not allow for extra conditions
     */
    protected List<T> findBySubname(String[] subnames, List<String> substringMatchProperties,
                    List<String> exactMatchProperties) {
        return findBySubname(subnames, null, null, substringMatchProperties, exactMatchProperties);
    }

    /**
     * A query builder for use by subclass DAOs. It makes it easy to match a fragment of a name or
     * identifier against multiple properties. This is intended for use in implementing
     * user-friendly dynamic searches; e.g., autocompleters.
     * 
     * @param subnames
     *                the name fragments to search on
     * @param extraConditions
     *                custom HQL conditions with which to constrain the fragment matches
     * @param extraParameters
     *                parameters for the custom conditions
     * @param substringMatchProperties
     *                a list of properties of the implementing object which should be matched as
     *                case-insensitive substrings
     * @param exactMatchProperties
     *                a list of properties which should be matched as case-insensitive full strings
     * @return a list of matching domain object instances
     */
    @SuppressWarnings("unchecked")
    protected List<T> findBySubname(String[] subnames, String extraConditions,
                    List<Object> extraParameters, List<String> substringMatchProperties,
                    List<String> exactMatchProperties) {
        StringBuilder query = new StringBuilder("from ").append(domainClass().getName()).append(
                        " o where ");
        if (extraConditions != null) query.append(extraConditions).append(" and ");
        List<Object> params = new LinkedList<Object>();
        if (extraParameters != null) params.addAll(extraParameters);

        for (int i = 0; i < subnames.length; i++) {
            buildSubnameQuery(subnames[i], query, params, substringMatchProperties,
                            exactMatchProperties);
            if (i < subnames.length - 1) query.append(" and ");
        }

        log.debug("query string = " + query);
        this.getHibernateTemplate().setMaxResults(30);
        return (getHibernateTemplate()).find(query.toString(), params.toArray());
    }

    protected void buildSubnameQuery(String subname, StringBuilder query, List<Object> params,
                    List<String> substringMatchProperties, List<String> exactMatchProperties) {
        query.append('(');
        if (hasAny(substringMatchProperties)) {
            for (Iterator<String> it = substringMatchProperties.iterator(); it.hasNext();) {
                String prop = it.next();
                query.append("LOWER(o.").append(prop).append(") LIKE ?");
                params.add('%' + subname.toLowerCase() + '%');
                if (it.hasNext()) query.append(" or ");
            }
            if (hasAny(exactMatchProperties)) {
                query.append(" or ");
            }
        }
        if (hasAny(exactMatchProperties)) {
            for (Iterator<String> it = exactMatchProperties.iterator(); it.hasNext();) {
                String prop = it.next();
                query.append("LOWER(o.").append(prop).append(") = ?");
                params.add(subname.toLowerCase());
                if (it.hasNext()) query.append(" or ");
            }
        }
        query.append(')');
    }

    private boolean hasAny(List<String> properties) {
        return properties != null && properties.size() > 0;
    }

}<commit_msg>fixing autocomplete search issue - hql exception in backend if user press spabe by mistake<commit_after>package edu.duke.cabig.c3pr.dao;

import gov.nih.nci.cabig.ctms.dao.AbstractDomainObjectDao;
import gov.nih.nci.cabig.ctms.domain.DomainObject;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

/**
 * Abstract BaseDao implementing BaseDao. Provides convenient methods for saving a base Dao
 * 
 * @author Priyatam
 */
public abstract class C3PRBaseDao<T extends DomainObject> extends AbstractDomainObjectDao<T> {

	private static Log log = LogFactory.getLog(C3PRBaseDao.class);

	/**
	 * Get Object by Id (based on domain class) with eager fetch of a single association
	 * 
	 * @param id
	 *                object id
	 * @param isEager
	 *                true if eager fetch is needed
	 * @param associationPath
	 *                the association 'name' needed to be loaded
	 * @return loaded persistent object
	 */
	public T getById(int id, boolean isEager, String associationPath) {
		if (isEager) {
			Criterion idCr = Restrictions.eq("id", id);
			Criteria criteria = getSession().createCriteria(domainClass()).setFetchMode(
					associationPath, FetchMode.JOIN).add(idCr);
			return (T) criteria.list().get(0);
		}
		return getById(id);
	}

	/*
	 * Must override in subclass to return the domain class reference in the dao
	 */
	public abstract Class<T> domainClass();

	/*
	 * Saves a domain object
	 */
	public void save(DomainObject domainObject) {
		getHibernateTemplate().saveOrUpdate(domainObject);
		postProcessSave();
	}

	/*
	 * Saves a domain object
	 */
	public void merge(DomainObject domainObject) {
		getHibernateTemplate().merge(domainObject);
		postProcessSave();
	}

	/**
	 * To be implemented by subclasses for custom extension of save
	 */
	protected void postProcessSave() {
		// default is empty implementation
	}

	/**
	 * A variation of {@link #findBySubname} that does not allow for extra conditions
	 */
	protected List<T> findBySubname(String[] subnames, List<String> substringMatchProperties,
			List<String> exactMatchProperties) {
		return findBySubname(subnames, null, null, substringMatchProperties, exactMatchProperties);
	}

	/**
	 * A query builder for use by subclass DAOs. It makes it easy to match a fragment of a name or
	 * identifier against multiple properties. This is intended for use in implementing
	 * user-friendly dynamic searches; e.g., autocompleters.
	 * 
	 * @param subnames
	 *                the name fragments to search on
	 * @param extraConditions
	 *                custom HQL conditions with which to constrain the fragment matches
	 * @param extraParameters
	 *                parameters for the custom conditions
	 * @param substringMatchProperties
	 *                a list of properties of the implementing object which should be matched as
	 *                case-insensitive substrings
	 * @param exactMatchProperties
	 *                a list of properties which should be matched as case-insensitive full strings
	 * @return a list of matching domain object instances
	 */
	@SuppressWarnings("unchecked")
	protected List<T> findBySubname(String[] subnames, String extraConditions,
			List<Object> extraParameters, List<String> substringMatchProperties,
			List<String> exactMatchProperties) {
		StringBuilder query = new StringBuilder("from ").append(domainClass().getName()).append(
		" o ");
		List<Object> params = new LinkedList<Object>();
		if(extraConditions != null || extraParameters != null || subnames.length > 0){
			query.append(" where ") ;
			if (extraConditions != null){
				query.append(extraConditions).append(" and ");
			}
			if (extraParameters != null) {
				params.addAll(extraParameters);
			}

			for (int i = 0; i < subnames.length; i++) {
				buildSubnameQuery(subnames[i], query, params, substringMatchProperties, exactMatchProperties);
				if (i < subnames.length - 1) query.append(" and ");
			}
		}

		log.debug("query string = " + query);
		this.getHibernateTemplate().setMaxResults(30);
		return (getHibernateTemplate()).find(query.toString(), params.toArray());
	}

	protected void buildSubnameQuery(String subname, StringBuilder query, List<Object> params,
			List<String> substringMatchProperties, List<String> exactMatchProperties) {
		query.append('(');
		if (hasAny(substringMatchProperties)) {
			for (Iterator<String> it = substringMatchProperties.iterator(); it.hasNext();) {
				String prop = it.next();
				query.append("LOWER(o.").append(prop).append(") LIKE ?");
				params.add('%' + subname.toLowerCase() + '%');
				if (it.hasNext()) query.append(" or ");
			}
			if (hasAny(exactMatchProperties)) {
				query.append(" or ");
			}
		}
		if (hasAny(exactMatchProperties)) {
			for (Iterator<String> it = exactMatchProperties.iterator(); it.hasNext();) {
				String prop = it.next();
				query.append("LOWER(o.").append(prop).append(") = ?");
				params.add(subname.toLowerCase());
				if (it.hasNext()) query.append(" or ");
			}
		}
		query.append(')');
	}

	private boolean hasAny(List<String> properties) {
		return properties != null && properties.size() > 0;
	}

}
{'fraction_non_alphanumeric': 0.10799464046449307, 'fraction_numerical': 0.0016971862438588657, 'mean_word_length': 2.933942375263528, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 42, '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': '3229844', 'n_tokens_mistral': 3237, 'n_tokens_neox': 3008, 'n_words': 852}