gov.nih.nci.cabio.portal.portlet.ReportService.java Source code

Java tutorial

Introduction

Here is the source code for gov.nih.nci.cabio.portal.portlet.ReportService.java

Source

/*L
 *  Copyright SAIC
 *
 *  Distributed under the OSI-approved BSD 3-Clause License.
 *  See http://ncip.github.com/cabio/LICENSE.txt for details.
 */

package gov.nih.nci.cabio.portal.portlet;

import gov.nih.nci.cabio.domain.ArrayReporterPhysicalLocation;
import gov.nih.nci.cabio.domain.ExpressionArrayReporter;
import gov.nih.nci.cabio.domain.Gene;
import gov.nih.nci.cabio.domain.GeneAgentAssociation;
import gov.nih.nci.cabio.domain.GeneDiseaseAssociation;
import gov.nih.nci.cabio.domain.GeneFunctionAssociation;
import gov.nih.nci.cabio.domain.GeneOntology;
import gov.nih.nci.cabio.domain.GenePhysicalLocation;
import gov.nih.nci.cabio.domain.MarkerPhysicalLocation;
import gov.nih.nci.cabio.domain.NucleicAcidPhysicalLocation;
import gov.nih.nci.cabio.domain.Pathway;
import gov.nih.nci.cabio.domain.SNPArrayReporter;
import gov.nih.nci.cabio.domain.SNPPhysicalLocation;
import gov.nih.nci.cabio.domain.TranscriptPhysicalLocation;
import gov.nih.nci.cabio.portal.portlet.canned.ClassObject;
import gov.nih.nci.cabio.portal.portlet.canned.LabeledObject;
import gov.nih.nci.common.util.QueryUtils;
import gov.nih.nci.common.util.ReflectionUtils;
import gov.nih.nci.system.applicationservice.ApplicationException;
import gov.nih.nci.system.applicationservice.CaBioApplicationService;
import gov.nih.nci.system.query.hibernate.HQLCriteria;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Convenience class for Templated Searches. The queries defined here do 
 * some eager-fetching of results. Note that due to an SDK limitation, it 
 * best to never eager-fetch associations with a cardinality greater than 1 
 * (i.e. any collection).
 * 
 * @author <a href="mailto:rokickik@mail.nih.gov">Konrad Rokicki</a>
 * @author <a href="mailto:sunj2@mail.nih.gov">Jim Sun</a>
 */
public class ReportService {

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

    private static final String PHYSICAL_LOCATION_HQL = "select loc from gov.nih.nci.cabio.domain.PhysicalLocation loc "
            + "left outer join fetch loc.chromosome as chrom " + "where ";

    private static final String GENES_BY_AGENT_HQL = "select assoc from gov.nih.nci.cabio.domain.GeneAgentAssociation assoc "
            + "left outer join fetch assoc.gene as gene " + "left outer join fetch assoc.agent as agent "
            + "where ";

    private static final String GENES_BY_AGENT_EVIDENCE_HQL = "select assoc from gov.nih.nci.cabio.domain.GeneAgentAssociation assoc "
            + "left join fetch assoc.gene as gene " + "left join fetch assoc.agent as agent "
            + "left join fetch assoc.evidenceCollection as evidence " + "where ";

    private static final String GENES_BY_AGENT_HQL_WHERE_NAME = "lower(agent.name) like ?";

    private static final String GENES_BY_AGENT_HQL_WHERE_CUI = "lower(agent.EVSId) like ?";

    private static final String GENES_BY_DISEASE_HQL = "select assoc from gov.nih.nci.cabio.domain.GeneDiseaseAssociation assoc "
            + "left outer join fetch assoc.gene as gene "
            + "left outer join fetch assoc.diseaseOntology as disease " + "where ";

    private static final String GENES_BY_DISEASE_EVIDENCE_HQL = "select assoc from gov.nih.nci.cabio.domain.GeneDiseaseAssociation assoc "
            + "left join fetch assoc.gene as gene " + "left join fetch assoc.diseaseOntology as disease "
            + "left join fetch assoc.evidenceCollection as evidence " + "where ";

    private static final String GENES_BY_DISEASE_HQL_WHERE_NAME = "lower(disease.name) like ?";

    private static final String GENES_BY_DISEASE_HQL_WHERE_CUI = "lower(disease.EVSId) like ?";

    private static final String GENE_ASSOCIATIONS_HQL = "select assoc from gov.nih.nci.cabio.domain.GeneFunctionAssociation assoc "
            + "left outer join fetch assoc.gene as gene " + "where ";

    private static final String GENE_ASSOCIATIONS_EVIDENCE_HQL = "select assoc from gov.nih.nci.cabio.domain.GeneFunctionAssociation assoc "
            + "left join fetch assoc.evidenceCollection as evidence " + "left join fetch assoc.gene as gene "
            + "where ";

    private static final String GENE_OR_ALIAS_HQL_WHERE = "gene.id in ("
            + "   select g.id from gov.nih.nci.cabio.domain.Gene g " + "   left join g.geneAliasCollection alias "
            + "   where lower(g.symbol) like ? or lower(alias.name) like ? " + ") ";

    private static final String EVIDENCE_NEGATION_STATUS_WHERE = "evidence.negationStatus=?";
    private static final String EVIDENCE_CELLLINE_STATUS_WHERE = "evidence.celllineStatus=?";
    private static final String EVIDENCE_SENTENCE_STATUS_WHERE = "evidence.sentenceStatus=?";

    private static final String REPORTERS_BY_GENE_HQL = "select reporter from gov.nih.nci.cabio.domain.ExpressionArrayReporter reporter "
            + "left outer join fetch reporter.microarray " + "left outer join fetch reporter.gene as gene "
            + "where ";

    private static final String REPORTERS_BY_SNP_HQL = "select reporter from gov.nih.nci.cabio.domain.SNPArrayReporter reporter "
            + "left outer join fetch reporter.SNP as SNP " + "left outer join fetch reporter.microarray "
            + "where ";

    private static final String REPORTERS_BY_SNP_HQL_WHERE = "lower(SNP.DBSNPID) = ?";

    private static final String GENES_BY_SYMBOL_HQL = "select gene from gov.nih.nci.cabio.domain.Gene gene "
            + "left outer join fetch gene.chromosome " + "left outer join fetch gene.taxon as taxon " + "where ";

    private static final String GO_BY_SYMBOL_HQL = "select distinct geneOntology from gov.nih.nci.cabio.domain.GeneOntology geneOntology "
            + "left outer join geneOntology.geneCollection as genes "
            + "left outer join genes.proteinCollection as proteins " + "where ";

    private static final String GO_BY_PROTEIN_NAME_HQL_WHERE = "lower(proteins.name) like ?";

    private static final String GO_BY_PROTEIN_ACCESSION_HQL_WHERE = "lower(proteins.primaryAccession) like ?";

    private static final String PATHWAY_BY_SYMBOL_HQL = "select pathway from gov.nih.nci.cabio.domain.Pathway pathway "
            + "left join fetch pathway.taxon as taxon " + "left join pathway.geneCollection as gene " + "where ";

    private static final String PATHWAY_BY_PROTEIN_HQL = "select pathway from gov.nih.nci.cabio.domain.Pathway pathway "
            + "left join fetch pathway.taxon as taxon " + "left join pathway.geneCollection as gene "
            + "left join gene.proteinCollection as proteins " + "where ";

    private static final String PATHWAY_BY_PROTEIN_NAME_HQL = "lower(proteins.name) like ?";

    private static final String PATHWAY_BY_PROTEIN_PRIMARY_ACCESSION_HQL = "lower(proteins.primaryAccession) like ?";

    private final CaBioApplicationService appService;

    private Map<Class, String> detailObjectHQL = new HashMap<Class, String>();

    static public String EVIDENCE_NEGATION_STATUS_NO = "no";
    static public String EVIDENCE_SENTENCE_STATUS_FINISHED = "finished";
    static public String EVIDENCE_CELLLINE_DATA = "no";

    /**
     * Constructor 
     * @param appService CaBioApplicationService
     */
    public ReportService(CaBioApplicationService appService) {
        this.appService = appService;

        detailObjectHQL.put(GenePhysicalLocation.class, PHYSICAL_LOCATION_HQL);
        detailObjectHQL.put(ArrayReporterPhysicalLocation.class, PHYSICAL_LOCATION_HQL);
        detailObjectHQL.put(NucleicAcidPhysicalLocation.class, PHYSICAL_LOCATION_HQL);
        detailObjectHQL.put(SNPPhysicalLocation.class, PHYSICAL_LOCATION_HQL);
        detailObjectHQL.put(MarkerPhysicalLocation.class, PHYSICAL_LOCATION_HQL);
        detailObjectHQL.put(TranscriptPhysicalLocation.class, PHYSICAL_LOCATION_HQL);

        detailObjectHQL.put(GeneAgentAssociation.class, GENES_BY_AGENT_HQL);
        detailObjectHQL.put(GeneDiseaseAssociation.class, GENES_BY_DISEASE_HQL);
        detailObjectHQL.put(GeneFunctionAssociation.class, GENE_ASSOCIATIONS_HQL);
        detailObjectHQL.put(ExpressionArrayReporter.class, REPORTERS_BY_GENE_HQL);
        detailObjectHQL.put(SNPArrayReporter.class, REPORTERS_BY_SNP_HQL);
        detailObjectHQL.put(Gene.class, GENES_BY_SYMBOL_HQL);
        detailObjectHQL.put(Pathway.class, PATHWAY_BY_SYMBOL_HQL);
    }

    /**
     * Returns the Collection association for the specified object and rolename.
     * @param clazz A caBIO bean class 
     * @param id Internal caBIO id of the object
     * @param targetAssoc rolename of the association to follow 
     * @return Object with certain associations preloaded
     * @throws ApplicationException
     */
    public List getDetailObjects(Class clazz, Long id, String targetAssoc, ClassObject config) throws Exception {

        if (!clazz.getPackage().getName().startsWith("gov.nih.nci.cabio.")) {
            throw new ApplicationException("Invalid class specified.");
        }

        Object criteria = clazz.newInstance();
        Class target = Class.forName(config.getName());
        ReflectionUtils.set(criteria, "id", id);

        // Construct HQL for getting the associated objects
        StringBuffer sb = new StringBuffer("select dest from " + config.getName() + " as dest ");

        // Eager fetch all the needed associations
        for (LabeledObject attr : config.getNestedAttributes()) {
            String first = attr.getFirstPart();
            if (ClassUtils.isSingular(target, first)) {
                sb.append("left join fetch dest." + first + " ");
            }
        }

        sb.append(", " + clazz.getName() + " as src ");
        sb.append("where src." + targetAssoc + ".id=dest.id and src=? ");

        String hql = sb.toString();
        List params = new ArrayList();
        params.add(criteria);
        List results = appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));

        // The above eager loads all many-to-1 associations needed for 
        // display of the class. The simpler (less efficient but more 
        // foolproof) way is this:
        //List results = appService.getAssociation(criteria, targetAssoc);

        if (results.isEmpty())
            return null;
        return results;
    }

    /**
     * Returns the detail object graph for the specified class/id combination.
     * @param clazz A caBIO bean class 
     * @param id Internal caBIO id of the object
     * @return Object with certain associations preloaded
     * @throws ApplicationException
     */
    public Object getDetailObject(Class clazz, Long id) throws ApplicationException {

        String hql = detailObjectHQL.get(clazz);

        if (hql == null) {
            hql = "from " + clazz.getName() + " o where o.id = ?";
        } else {
            Matcher m = Pattern.compile("^select (\\w+?) from.*").matcher(hql);
            m.find();
            String target = m.group(1);
            hql += target + ".id = ?";
        }

        List<Long> params = new ArrayList<Long>();
        params.add(id);
        List results = appService.query(new HQLCriteria(hql, params));

        if (results.isEmpty())
            return null;
        return results.iterator().next();
    }

    /**
     * Returns all gene associations for a given agent.  
     * @param agentNameOrCui Agent.name or Agent.EVSId
     * @return List of GeneAgentAssociation, with preloaded genes and agents
     * @throws ApplicationException
     */
    public List<GeneAgentAssociation> getGenesByAgent(String agentNameOrCui) throws ApplicationException {

        String nameOrCui = convertInput(agentNameOrCui);
        List<String> params = getListWithId(nameOrCui);

        String hql = GENES_BY_AGENT_HQL;
        if (nameOrCui.matches("^c(\\d+)%?$")) {
            hql += GENES_BY_AGENT_HQL_WHERE_CUI;
        } else {
            hql += GENES_BY_AGENT_HQL_WHERE_NAME;
        }

        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all gene associations for a given agent.  
     * @param agentNameOrCui Agent.name or Agent.EVSId
     * @param negationStatus   Evidence.negationStatus
     * @param finishedSentence Evidence.finishedSentence
     * @param celllineStatus   Evidence.celllineStatus          
     * @return List of GeneAgentAssociation, with preloaded genes and agents
     * @throws ApplicationException
     */
    public List<GeneAgentAssociation> getGenesByAgentWithEvidenceProperties(String agentNameOrCui,
            String negationStatus, String finishedSentence, String celllineStatus) throws ApplicationException {

        String nameOrCui = convertInput(agentNameOrCui);
        List<String> params = getListWithId(nameOrCui);

        String hql = GENES_BY_AGENT_EVIDENCE_HQL;
        if (nameOrCui.matches("^c(\\d+)%?$")) {
            hql += GENES_BY_AGENT_HQL_WHERE_CUI;
        } else {
            hql += GENES_BY_AGENT_HQL_WHERE_NAME;
        }

        hql += composeEvidencePropertiesWhereClause(negationStatus, finishedSentence, celllineStatus, params);

        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all gene associations for a given disease.  
     * @param diseaseNameOrCui Disease.name or Disease.EVSId
     * @return List of GeneDiseaseAssociation, with preloaded genes and diseases
     * @throws ApplicationException
     */
    public List<GeneDiseaseAssociation> getGenesByDisease(String diseaseNameOrCui) throws ApplicationException {

        String nameOrCui = convertInput(diseaseNameOrCui);
        List<String> params = getListWithId(nameOrCui);

        String hql = GENES_BY_DISEASE_HQL;
        if (nameOrCui.matches("^c(\\d+)%?$")) {
            hql += GENES_BY_DISEASE_HQL_WHERE_CUI;
        } else {
            hql += GENES_BY_DISEASE_HQL_WHERE_NAME;
        }

        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all gene associations for a given disease
     * @param diseaseNameOrCui Disease.name or Disease.EVSId
     * @param negationStatus   Evidence.negationStatus
     * @param finishedSentence Evidence.finishedSentence
     * @param celllineStatus   Evidence.celllineStatus     
     * @return List of GeneDiseaseAssociation, with preloaded genes and diseases
     * @throws ApplicationException
     */
    public List<GeneDiseaseAssociation> getGenesByDiseaseWithEvidenceProperties(String diseaseNameOrCui,
            String negationStatus, String finishedSentence, String celllineStatus) throws ApplicationException {

        String nameOrCui = convertInput(diseaseNameOrCui);
        List<String> params = getListWithId(nameOrCui);

        String hql = GENES_BY_DISEASE_EVIDENCE_HQL;
        if (nameOrCui.matches("^c(\\d+)%?$")) {
            hql += GENES_BY_DISEASE_HQL_WHERE_CUI;
        } else {
            hql += GENES_BY_DISEASE_HQL_WHERE_NAME;
        }

        hql += composeEvidencePropertiesWhereClause(negationStatus, finishedSentence, celllineStatus, params);

        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all gene associations for a given gene symbol.  
     * @param geneSymbol Gene.symbol or Gene.hugoSymbol
     * @param negationStatus   Evidence.negationStatus
     * @param finishedSentence Evidence.finishedSentence
     * @param celllineStatus   Evidence.celllineStatus     
     * @return List of GeneDiseaseAssociation, with preloaded genes 
     * @throws ApplicationException
     */
    public List<GeneFunctionAssociation> getGeneAssociationsWithEvidenceProperties(String geneSymbol,
            String negationStatus, String finishedSentence, String celllineStatus) throws ApplicationException {

        String hql = GENE_ASSOCIATIONS_EVIDENCE_HQL + GENE_OR_ALIAS_HQL_WHERE;
        String symbol = convertInput(geneSymbol);
        List<String> params = getListWithId(symbol);
        params.add(symbol);

        hql += composeEvidencePropertiesWhereClause(negationStatus, finishedSentence, celllineStatus, params);

        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * @param negationStatus   Evidence.negationStatus
     * @param finishedSentence Evidence.finishedSentence
     * @param celllineStatus   Evidence.celllineStatus
     * @param params the parameters for HQL query
     * @return where clause for the Evidence properties 
     */
    private String composeEvidencePropertiesWhereClause(String negationStatus, String unfinishedSentence,
            String celllineStatus, List<String> params) {
        StringBuffer evWhere = new StringBuffer();

        if (!"on".equalsIgnoreCase(negationStatus)) {
            evWhere.append(" and " + EVIDENCE_NEGATION_STATUS_WHERE);
            params.add(EVIDENCE_NEGATION_STATUS_NO);
        } // otherwise, query for all the negationStatus

        // by default, search only finished sentence. If selected, returns all
        if (!"on".equalsIgnoreCase(unfinishedSentence)) {
            evWhere.append(" and " + EVIDENCE_SENTENCE_STATUS_WHERE);
            params.add(EVIDENCE_SENTENCE_STATUS_FINISHED);
        }

        // by default, search only "no" cellline status. Otherwise, return all 
        if (!"on".equalsIgnoreCase(celllineStatus)) {
            evWhere.append(" and " + EVIDENCE_CELLLINE_STATUS_WHERE);
            params.add(EVIDENCE_CELLLINE_DATA);
        }

        return evWhere.toString();
    }

    /**
     * Returns all gene associations for a given gene symbol.  
     * @param geneSymbol Gene.symbol or Gene.hugoSymbol
     * @return List of GeneDiseaseAssociation, with preloaded genes 
     * @throws ApplicationException
     */
    public List<GeneFunctionAssociation> getGeneAssociations(String geneSymbol) throws ApplicationException {

        String hql = GENE_ASSOCIATIONS_HQL + GENE_OR_ALIAS_HQL_WHERE;
        String symbol = convertInput(geneSymbol);
        List<String> params = getListWithId(symbol);
        params.add(symbol);
        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all reporters for a given gene symbol.  
     * @param geneSymbol Gene.symbol or Gene.hugoSymbol
     * @return List of ExpressionArrayReporter, with preloaded genes and microarrays
     * @throws ApplicationException
     */
    public List<ExpressionArrayReporter> getReportersByGene(String geneSymbol) throws ApplicationException {

        String hql = REPORTERS_BY_GENE_HQL + GENE_OR_ALIAS_HQL_WHERE;
        String symbol = convertInput(geneSymbol);
        List<String> params = getListWithId(symbol);
        params.add(symbol);
        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all reporters for a given SNP.  
     * @param dbSNPId SNP.DBSNPID
     * @return List of SNPArrayReporter, with preloaded genes and SNPs
     * @throws ApplicationException
     */
    public List<SNPArrayReporter> getReportersBySNP(String dbSNPId) throws ApplicationException {

        String hql = REPORTERS_BY_SNP_HQL + REPORTERS_BY_SNP_HQL_WHERE;
        List<String> params = new ArrayList<String>();
        params.add(dbSNPId.toLowerCase().trim());
        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all genes for a given symbol.  
     * @param geneSymbol
     * @return List of Genes, with preloaded taxons, chromosomes, and the 
     *         locus link id in DatabaseCrossReference. 
     * @throws ApplicationException
     */
    public List<Gene> getGenesBySymbol(String geneSymbol) throws ApplicationException {

        String hql = GENES_BY_SYMBOL_HQL + GENE_OR_ALIAS_HQL_WHERE;
        String symbol = convertInput(geneSymbol);
        List<String> params = getListWithId(symbol);
        params.add(symbol);
        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all gene ontology associations for a given protein name or accession.  
     * @param proteinNameAccession
     * @return List of GeneOntologies. 
     * @throws ApplicationException
     */
    public List<GeneOntology> getGoByProtein(String proteinNameAccession) throws ApplicationException {

        String hql = GO_BY_SYMBOL_HQL + GO_BY_PROTEIN_NAME_HQL_WHERE + " OR " + GO_BY_PROTEIN_ACCESSION_HQL_WHERE;
        List<String> params = getListWithId(convertInput(proteinNameAccession));
        params.add(convertInput(proteinNameAccession));
        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all pathways for a given name.
     * @param pathwayName (Name of the pathway)
     * @return List of Pathways. 
     * @throws ApplicationException
     */
    public List<Pathway> getPathwaysByName(String pathwayName) throws ApplicationException {

        String inputName = pathwayName.trim();

        if ("".equals(inputName))
            return new ArrayList<Pathway>();

        Pathway pathway = new Pathway();
        pathway.setName(inputName);

        return appService.search(Pathway.class, pathway);
    }

    /**
     * Returns all pathways for a given protein name or accession.
     * @param proteinNameAccession (protein Name or accession)
     * @return List of Pathways. 
     * @throws ApplicationException
     */
    public List<Pathway> getPathwaysByProtein(String proteinNameAccession) throws ApplicationException {

        String inputNameAccession = proteinNameAccession.trim();

        String hql = PATHWAY_BY_PROTEIN_HQL + PATHWAY_BY_PROTEIN_NAME_HQL + " OR "
                + PATHWAY_BY_PROTEIN_PRIMARY_ACCESSION_HQL;
        List<String> params = getListWithId(convertInput(inputNameAccession));
        params.add(convertInput(inputNameAccession));
        return appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params));
    }

    /**
     * Returns all pathways for a given source.
     * @param pathwayName (Source of the pathway)
     * @return List of Pathways. 
     * @throws ApplicationException
     */
    public List<Pathway> getPathwaysBySource(String pathwaySource) throws ApplicationException {

        String inputSource = pathwaySource.trim();

        if ("".equals(inputSource))
            return new ArrayList<Pathway>();

        Pathway pathway = new Pathway();
        pathway.setSource(inputSource);

        return appService.search(Pathway.class, pathway);
    }

    /**
     * Returns all pathways for a given symbol.  
     * @param geneSymbol (Gene Symbol)
     * @return List of Pathways. 
     * @throws ApplicationException
     */
    public List<Pathway> getPathwaysByGeneSymbol(String geneSymbol) throws ApplicationException {

        String hql = PATHWAY_BY_SYMBOL_HQL + GENE_OR_ALIAS_HQL_WHERE;
        String symbol = convertInput(geneSymbol);
        List<String> params = getListWithId(symbol);
        params.add(symbol);
        return filterDuplicates(appService.query(new HQLCriteria(hql, QueryUtils.createCountQuery(hql), params)));
    }

    /**
     * Filters duplicate objects based on id. The objects must all have a 
     * getId() method.
     * @param objects
     * @return
     */
    private List filterDuplicates(List<? extends Object> objects) throws ApplicationException {
        Map map = new LinkedHashMap();
        try {
            for (Object o : objects) {
                map.put(ReflectionUtils.get(o, "id"), o);
            }
        } catch (Exception e) {
            throw new ApplicationException(e);
        }
        return new ArrayList(map.values());
    }

    /**
     * Converts input for use in HQL. Converts to lower case and replaces
     * star (*) wildcards with amperstand (%) wildcards.
     * @param input
     * @return converted input
     */
    private String convertInput(String input) {
        return input.toLowerCase().trim().replaceAll("\\*", "%");
    }

    /**
     * Shortcut method to create a parameter array with the same parameter twice.
     * @param id
     * @return
     */
    private List<String> getListWithId(String id) {
        List<String> params = new ArrayList<String>();
        params.add(id);
        return params;
    }
}