gov.nih.nci.ispy.web.helper.ReportGeneratorHelper.java Source code

Java tutorial

Introduction

Here is the source code for gov.nih.nci.ispy.web.helper.ReportGeneratorHelper.java

Source

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

package gov.nih.nci.ispy.web.helper;

import gov.nih.nci.caintegrator.application.bean.FindingReportBean;
import gov.nih.nci.caintegrator.application.cache.PresentationTierCache;
import gov.nih.nci.caintegrator.application.report.LevelOfExpressionIHCReport;
import gov.nih.nci.caintegrator.application.report.LossOfExpressionIHCReport;
import gov.nih.nci.caintegrator.application.report.P53Report;
import gov.nih.nci.caintegrator.service.findings.ClassComparisonFinding;
import gov.nih.nci.caintegrator.service.findings.Finding;
import gov.nih.nci.ispy.cache.ISPYContextListener;
import gov.nih.nci.ispy.service.findings.ISPYIHCLevelOfExpressionFinding;
import gov.nih.nci.ispy.service.findings.ISPYIHCLossOfExpressionFinding;
import gov.nih.nci.ispy.service.findings.P53Finding;
import gov.nih.nci.ispy.util.ApplicationContext;
import gov.nih.nci.ispy.util.MoreStringUtils;
import gov.nih.nci.ispy.util.ispyConstants;
import gov.nih.nci.ispy.web.factory.ApplicationFactory;
import gov.nih.nci.ispy.web.xml.ClassComparisonReport;
import gov.nih.nci.ispy.web.xml.Transformer;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.io.HTMLWriter;
import org.dom4j.io.OutputFormat;

/**
 * The ReportGeneratorHelper was written to act as a Report Generation manager
 * for the UI. It provides a single avenue where, if a UI element has a Query to
 * execute or the cache key to a previously stored Resultant, the necesary calls
 * are made to generate an XML document representing the report. The generated
 * XML will then be stored in a ReportBean that will also contain the cache key
 * where the resultant can be called again, if needed.
 * 
 * @author BauerD, LandyR 
 * Feb 8, 2005
 * 
 */

public class ReportGeneratorHelper {
    //This is the general purpose Nautilus Logger
    private static Logger logger = Logger.getLogger(ReportGeneratorHelper.class);
    //this is the XML logger for the reports
    private static Logger xmlLogger;
    //This is the element that is used to store all relevant report data
    //it stores the resultant, the sessionId, the latest reportXML
    //private ReportBean _reportBean;
    //private CompoundQuery _cQuery;
    private String _queryName = null;
    private String _sessionId = null;
    private static Properties applicationResources = applicationResources = ApplicationContext.getLabelProperties();
    private PresentationTierCache presentationTierCache = ApplicationFactory.getPresentationTierCache();
    //Check the applications resource file and turn on report xml logging if 
    //property nautilus.xml_logging = true, else then no xml report logging.
    private static boolean xmlLogging;
    static {
        String property = (String) applicationResources.get("nautilus.xml_logging");
        if ("true".equals(property)) {
            xmlLogging = true;
            //Get the XML_LOGGER specified in log4j.properties
            xmlLogger = Logger.getLogger("XML_LOGGER");
        } else {
            xmlLogging = false;
        }

    }
    /**
     * This constructor is intended to be used by the UI when it needs to apply
     * a filter on a previously run report that requires the regeneration of the
     * report XML.  At this time it is only a "Show All Values" and "Copy Number
     * Filter" report.
     * 
     * This means that there must be a previous query that has been executed and
     * stored in the cache that can retrieveed.  The ReportBean given should be
     * the bean for the report that was previously generated and the user would
     * like to filter.
     * 
     * @param reportBean
     * @param filterParams -- this is all the XML filterParam values 
     */
    /*
     public ReportGeneratorHelper(ReportBean reportBean, Map filterParams) {
       logger.debug("Calling ReportGeneratorHelper to filter resultant");
        Resultant oldResultant = reportBean.getResultant();
       Resultant newResultant;
       //Get the sessionId and name for this resultant, this works because,
       //at the present time there is only one type of query that is ever
       //run, and that is a CompoundQuery if that changes than it will be
       //necesary to modify the code here and many other places
       String sessionId = ((CompoundQuery)(reportBean.getAssociatedQuery())).getSessionId();
       String oldQueryName = ((CompoundQuery)(reportBean.getAssociatedQuery())).getQueryName();
       String newQueryName = "";
       String filter_element = (String)filterParams.get("filter_element");
       try {
     //Apply the copy_number filter
     if("copy_number".equals(filter_element)) {
        logger.debug("Performing CopyNumber filter");
        //execute copy number filter query
        OperatorType operator = (OperatorType)filterParams.get("filter_value4");
        Integer consecutiveCalls = (Integer)filterParams.get("filter_value5");
        Integer percentCalls = (Integer)filterParams.get("filter_value6");
        logger.debug("Old QueryName: "+oldQueryName);
        newResultant = ResultsetManager.filterCopyNumber(oldResultant,consecutiveCalls,percentCalls,operator);
        newQueryName = nameFilterQuery(oldQueryName, RembrandtConstants.FILTER_REPORT_SUFFIX);
        logger.debug("New QueryName: "+newQueryName);
     }else {
        logger.debug("Performing a Show All Values Query");
        //
         //* This is a hack...  we need to make sure that this isn't
         //* something other than a show all values query
         //
        logger.debug("Old QueryName: "+oldQueryName);
        newResultant = ResultsetManager.executeShowAllQuery(oldResultant);
        newQueryName = nameFilterQuery(oldQueryName, RembrandtConstants.SHOW_ALL_VALUES_SUFFIX);
        logger.debug("New QueryName: "+newQueryName);
     }
     //*
     // * We have to rename the resultant using the new query name with the
     // * added suffix
     // 
     if(newResultant!=null) {
        logger.debug("Setting newQueryName in resultant's associated query");
        newResultant.getAssociatedQuery().setQueryName(newQueryName);
     }
     //*
     // * At present the executeShowAllQuery(Resultant) method does not 
     // * pass through the sessionId or the queryName, in the associated
     // * Query in the showAllResults. So it is necesary to get the query
     // * and set the sessionId and the queryName.  
     //
     CompoundQuery query = (CompoundQuery)reportBean.getAssociatedQuery();
     //check the associated query to make sure that it is a compound query
     //also sets the _cQuery attribute
           
     checkCompoundQuery(query);
     //check the sessionId that it isn't null or empty and set _sessionId in _cQuery
     checkSessionId(sessionId);
     //check that we have an old QueryName and set the class variable _queryName,
     //adding that it is a all values report
     checkQueryName( newQueryName);
    //         create a new ReportBean
     _reportBean = new ReportBean();
     //store the annotated query in the reportBean
     _reportBean.setAssociatedQuery(_cQuery);
     //store the results into the report bean
     _reportBean.setResultant(newResultant);
     //store the cache key that can be used to retrieve this bean later
     _reportBean.setResultantCacheKey(_queryName);
     //send the filterParamMap for processing and store in _reportBean
     _reportBean.setFilterParams(processFilterParamMap(filterParams));
     //generate the reportXML and store in the ReportBean
     generateReportXML();
     //drop this ReportBean in the session cache, use the _queryName as the 
     //parameter
     presentationTierCache.addToSessionCache(_sessionId,_queryName,_reportBean);
           
       }catch(Exception e) {
     logger.error("Exception when trying to generate a Show All Values Report");
     logger.error(e);
       }
       //All done...
    }
        
    */

    /**
     * This is intended to be used to generate a ReportBean when you have a
     * query and want to reduce the result set by limiting the results to 
     * sample ids listed in the String[] sampleIds. As it is currently implemented
     * it does not check the cache for any result sets, because at present, we
     * execute the query all over again.  
     * 
     * In the future if performance is important we may consider just taking the
     * already existing result set and just extract the relevant sampleIds 
     * 
     * @param query --currently a CompoundQuery that you are selecting sample
     * ids from. No other Queriable object will actually work.  I know,I know
     * bad design. But this is to allow for the possibility of other types 
     * in the future.  We may later decide to constrain this to a CompoundQuery
     * but for now... well it is just going to have to be the way it is.
     * @param sampleIds --this is the array of sample ids that you would like to
     * contstrain
     * @throws Exception
     */
    /*
       public ReportGeneratorHelper(Queriable query, String[] sampleIds) throws IllegalStateException {
          //Clone the original query so that we do not modify it when we add samples to it
          query = (CompoundQuery)query.clone();
          //check the query to make sure that it is a compound query
          checkCompoundQuery(query);
          //check to make sure that we have a sessionId
          checkSessionId( _cQuery.getSessionId());
          //check that we have a queryName
          checkQueryName( _cQuery.getQueryName());
          //create a new ReportBean
          _reportBean = new ReportBean();
          Resultant sampleIdResults = null;
          try {   
     sampleIdResults = ResultsetManager.executeCompoundQuery(_cQuery, sampleIds);         
          }catch(Exception e) {
     logger.error("The ResultsetManager threw some exception");
     logger.error(e);
          }
          //*
          // * Make sure we got a result set back and then store all the information
          // * in the bean.
          //
          if(sampleIdResults!=null&&sampleIdResults.getResultsContainer()!=null) {
        sampleIdResults.getAssociatedQuery().setQueryName(_cQuery.getQueryName());
     //store the results and query into the report bean
        _reportBean.setAssociatedQuery(sampleIdResults.getAssociatedQuery());
     _reportBean.setResultant(sampleIdResults);
          }else {
     throw new IllegalStateException("ResultsetManager returned an empty resultant or threw an Exception");
          }
          //store the cache key that can be used to retrieve this bean later
          _reportBean.setResultantCacheKey(_queryName);
          //this is a result set
          _reportBean.setSampleSetQuery(true);
          //generate the reportXML and store in the ReportBean
          generateReportXML();
       }
           
       */

    /**
     * This constructor uses a TemplateMethod pattern to perform the following
     * tasks (They must happen in this order, though some may be omitted if the
     * use case does not require it): 
     *       1-Check to see if the query is a CompoundQuery and cast if is
     *       2-Check that there is a sessionId specified for the query
     *       3-Check that we have a query name for the CompoundQuery
     *       4-Check the SessionCache for any stored results for this query
     *      to avoid running to the database if not needed.
     *      5-Execute the query if there is no result set to use in the cache
     *      6-Generate the report xml based on the desired view
     *             
     * @param query --the query that you want some new view (Report) of
     */
    /*
    public ReportGeneratorHelper(Queriable query, Map filterParams) {
       try {
         
     //check the query to make sure that it is a compound query
     checkCompoundQuery(query);
     //check to make sure that we have a sessionId
     checkSessionId( _cQuery.getSessionId());
     //check that we have a queryName
     checkQueryName( _cQuery.getQueryName());
        
     //*
     // * If the _reportBean is null then we know that we could not
     // * find an appropriate result set in the session cache. So
     // * lets run a query and get a result. Always run a query
     // * if it is a preview report.
     // * 
     // 
     if (_reportBean == null||RembrandtConstants.PREVIEW_RESULTS.equals(_queryName)) {
        logger.debug("Executing Query");
        if(RembrandtConstants.PREVIEW_RESULTS.equals(_queryName))   {
           //put this in the map for preview
           filterParams.put("showSampleSelect", new String("false"));
        }
        executeQuery();
     }
     if(_reportBean != null){//if its a valid query
        _reportBean.setFilterParams(processFilterParamMap(filterParams));
        this.generateReportXML();
     }
       }catch(Exception e) {
     logger.error("Unable to create the ReportBean");
     logger.error(e);
           
        
       }
    }
    */

    public ReportGeneratorHelper(Finding finding) {

    }

    /**
     * Checks the Queriable object and determines if it is a CompoundQuery.  If
     * so then set the class variable _cQuery = (CompoundQuery)query else
     * throw a new UnsupportedOperationException as we can not currently handle 
     * anything but CompoundQueries at this time.  I know that it doesn't make 
     * much sense to only allow a single implementation of the Queriable Interface
     * to really be passed when we specify in the signature that any Queriable
     * object will do.  It is just that in order to avoid tons of casting and
     * maintain flexibility for later implementations I did it this way.
     *  
     * @param query
     * @throws UnsupportedOperationException
     */
    /*
    private void checkCompoundQuery(Queriable query) throws UnsupportedOperationException {
       if (query != null && query instanceof CompoundQuery) {
     //sets the class variable _cQuery 
     _cQuery = (CompoundQuery)query;
       }else {
     //*
     // * Some other object implementing the Queriable interface has been
     // * passed. Currently we only support the compound query. But that is
     // * not to say that we won't later support others. Hence, the if-else
     // * statement here. I'll bet we want the run report button to use
     // * this class so I better add some code here if we just get a query.
     // 
     logger.error("Non compound query submitted");
     throw new UnsupportedOperationException(
           "You must pass a CompoundQuery at this time");
       }
    }
    */

    /**
     * Check the sessionId in the Queriable object that we have gotten
     * @param sessionId
     * @throws IllegalStateException
     */
    /*
    private void checkSessionId(String sessionId)throws IllegalStateException {
       if (sessionId != null && !sessionId.equals("")) {
     _sessionId = sessionId;
     _cQuery.setSessionId(sessionId);
       } else {
     //*
     // * We can not store the resultSet without a unique cache to
     // * store it in. And since we are currently implementing a
      //* session based cache system, that unique cache id should
      //* be the session id. If there is no session id, than we can
      //* assume that something is really wrong so throw a new
      //* IllegalStateException
      //
     logger.error("sessionId is empty for the compoundQuery");
     throw new IllegalStateException(
           "There does not appear to be a session associated with this query");
       }
    }
    */

    /**
     * make sure that we have a name for our report
     * @param queryName
     */
    /*
    private void checkQueryName(String queryName) {
       if (!"".equals(queryName)&& queryName != null){
     _queryName = queryName;
       }else {
     //*
     // * If the query name is empty than we can assume that
     // * the user has no interest in storing the query for
     // * later use. However the user may still want to use the
     // * current query report in other ways, like changing the
     // * view or downloading it. SO we should probably keep it
     // * around for a little bit. We do this by giving it a
     // * fixed temp name to use as a session cache key.
     // * 
     // 
     _queryName = presentationTierCache.getTempReportName(_sessionId);
         
       }
       _cQuery.setQueryName(_queryName);
    }
    */

    /**
     * check the session cache for the results sets for the query
     * @param view
     */
    /*
    private void checkCache(View view) {
       //*
       // * Use the sessionId to get the cache and see if 
       // * a result set already exists for the queryName we have been 
       // * given.
       // 
       _reportBean = presentationTierCache.getReportBean(_sessionId, _queryName, view);
    }
    */

    /**
     * This method will take the class variable ReportBean _reportBean and 
     * create the correct XML representation for the desired view of the results.  When
     * completed it adds the XML to the _reportBean and drops the _reportBean
     * into the sessionCache for later retrieval when needed
     * 
     * @throws IllegalStateException this is thrown when there is no resultant
     * found in _reportBean
     */
    /*
    private void generateReportXML() throws IllegalStateException {
           
       //*
       // * Get the correct report XML generator for the desired view
       // * of the results.
       // * 
       //
       Document reportXML = null;
       if (_reportBean != null) {
     //*
     // * We need to check the resultant to make sure that
     // * the database has actually return something for the associated
     // * query or filter.
     // 
     Resultant resultant = _reportBean.getResultant();
     if(resultant!=null) {
        try {
           Viewable oldView = resultant.getAssociatedView();
                //make sure old view is not null, if so, set it to the same as new view.
                if(oldView == null){
                    oldView = _cQuery.getAssociatedView();
                }
           Viewable newView = _cQuery.getAssociatedView();
           Map filterParams = _reportBean.getFilterParams();
           //*
           // * Make sure that we change the view on the resultSet
           // * if the user changes the desired view from already
           // * stored view of the results
           //
           if(!oldView.equals(newView)||_reportBean.getReportXML()==null) {
              //we must generate a new XML document for the
              //view they want
              logger.debug("Generating XML");
              ReportGenerator reportGen = ReportGeneratorFactory
                    .getReportGenerator(newView);
              resultant.setAssociatedView(newView);
              reportXML = reportGen.getReportXML(resultant, filterParams);
              logger.debug("Completed Generating XML");
           }else {
              //Old view is the current view
              logger.debug("Fetching report XML from reportBean");
              reportXML = _reportBean.getReportXML();
           }
        }catch(NullPointerException npe) {
           logger.error("The resultant has a null value for something that was needed");
           logger.error(npe);
        }
     }
            
     //XML Report Logging
     if(xmlLogging) {
        try {
           StringWriter out = new StringWriter();
           OutputFormat outformat = OutputFormat.createPrettyPrint();
           XMLWriter writer = new XMLWriter(out, outformat);
           writer.write(reportXML);
           writer.flush();
           xmlLogger.debug(out.getBuffer());
        }catch(IOException ioe) {
           logger.error("There was an error writing the XML to log");
           logger.error(ioe);
        }catch(NullPointerException npe){
           logger.debug("There is no XML to log!");
        }
     }
     _reportBean.setReportXML(reportXML);
     presentationTierCache.addToSessionCache(_sessionId,_queryName,_reportBean);
                     
             
       }else {
     throw new IllegalStateException("There is no resultant to create report");
       }
    }
    */

    //   //ISPY USES THIS _ RCL 3/2
    //   public static void generateReportXML(Finding finding)   {
    //      //TODO: shouldnt be called until findings are populated (!= running)
    //      //TODO: is threadsafe?
    //      //TODO: instance of
    //      Document xmlDocument = ClassComparisonReport.getReportXML(finding, new HashMap());
    //      FindingReportBean frb = new FindingReportBean();
    //      frb.setFinding(finding);
    //      frb.setXmlDoc(xmlDocument);
    //      logger.debug(xmlDocument.asXML());
    //      //TODO: check cache for collision - second param is key
    //      ApplicationFactory.getPresentationTierCache().addPersistableToSessionCache(finding.getSessionId(),finding.getTaskId(), frb);
    //   }

    public static void generateReportXML(Finding finding) {
        //TODO: shouldnt be called until findings are populated (!= running)
        //TODO: is threadsafe?
        Document xmlDocument = null;
        if (finding instanceof P53Finding) {
            xmlDocument = P53Report.getReportXML(finding, new HashMap());
        }
        if (finding instanceof ISPYIHCLevelOfExpressionFinding) {
            xmlDocument = LevelOfExpressionIHCReport.getReportXML(finding, new HashMap());
        }
        if (finding instanceof ISPYIHCLossOfExpressionFinding) {
            xmlDocument = LossOfExpressionIHCReport.getReportXML(finding, new HashMap());
        } else if (finding instanceof ClassComparisonFinding) {
            xmlDocument = ClassComparisonReport.getReportXML(finding, new HashMap());
        }
        FindingReportBean frb = new FindingReportBean();
        frb.setFinding(finding);
        frb.setXmlDoc(xmlDocument);
        //logger.debug(xmlDocument.asXML());
        //TODO: check cache for collision - second param is key
        ApplicationFactory.getPresentationTierCache().addPersistableToSessionCache(finding.getSessionId(),
                finding.getTaskId(), frb);
    }

    /**
     * This executes the current Compound Query that is referenced in the _cQuery
     * class scope variable.  Stores this _cQuery in the ReportBean as the
     * associatedQuery
     * @throws Exception
     */
    /*
    private void executeQuery() throws Exception{
       //empty the cache before executing the query again
       presentationTierCache.addToSessionCache(_sessionId,_queryName,null);
           
       if(_cQuery!=null) {
     Resultant resultant = ResultsetManager.executeCompoundQuery(_cQuery);
     //
     // * Create the _reportBean that will store everything we 
     // * may need later when messing with the reports associated
     // * with this result set.  This _reportBean will also 
     // * be stored in the cache.
     //   
     if(resultant != null){
        _reportBean = new ReportBean();
        _reportBean.setAssociatedQuery(_cQuery);
        _reportBean.setResultant(resultant);
        //The cache key will always be the compound query name
        _reportBean.setResultantCacheKey(_cQuery.getQueryName());
     }
     else{
        logger.debug("resultant is Null.  no results returned!");
        //_reportBean = null;
        _reportBean = new ReportBean();
        _reportBean.setAssociatedQuery(_cQuery);
        //_reportBean.setResultant(resultant);
        //The cache key will always be the compound query name
        _reportBean.setResultantCacheKey(_cQuery.getQueryName());
     }      
       }else{
     logger.error("Compound Query is Null.  Can not execute!");
     throw new NullPointerException("CompoundQuery is null.");
       }
    }
    */

    /**
     * Returns the ReportBean that was generated by the constructor
     * @return --constructed ReportBean
     */
    /*
    public ReportBean getReportBean() {
       return _reportBean;
    }
    */

    /**
     * This static method will render a query report of the passed reportXML, in
     * HTML using the XSLT whose name has been passed, to the jsp whose 
     * jspWriter has been passed. The request is used to acquire any filter 
     * params that may have been added to the request and that may be applicable
     * to the XSLT.
     *  
     * @param request --the request that will contain any parameters you want applied
     * to the XSLT that you specify
     * @param reportXML -- this is the XML that you want transformed to HTML
     * @param xsltFilename --this the XSLT that you want to use
     * @param out --the JSPWriter you want the transformed document to go to...
     */
    /*
    public static void renderReport(HttpServletRequest request, Document reportXML, String xsltFilename, JspWriter out) {
       File styleSheet = new File(RembrandtContextListener.getContextPath()+"/XSL/"+xsltFilename);
       // load the transformer using JAX
       logger.debug("Applying XSLT "+xsltFilename);
    Transformer transformer;
       try {
     transformer = new Transformer(styleSheet, (HashMap)request.getAttribute(RembrandtConstants.FILTER_PARAM_MAP));
       Document transformedDoc = transformer.transform(reportXML);
           
       //*
       // * right now this assumes that we will only have one XSL for CSV
       // * and it checks for that as we do not want to "pretty print" the CSV, we
       // * only want to spit it out as a string, or formatting gets messed up
       // * we will of course want to pretty print the XHTML for the graphical reports
       // * later we can change this to handle mult XSL CSVs
       // * RCL
       // 
       if(!xsltFilename.equals(RembrandtConstants.DEFAULT_XSLT_CSV_FILENAME)){
           OutputFormat format = OutputFormat.createPrettyPrint();
           XMLWriter writer;
           writer = new XMLWriter(out, format );
               
           writer.write( transformedDoc );
           writer.close();
       }
       else   {
           String csv = transformedDoc.getStringValue();
           csv.trim();
           out.println(csv);
       }
       }catch (UnsupportedEncodingException uee) {
     logger.error("UnsupportedEncodingException");
     logger.error(uee);
       }catch (IOException ioe) {
     logger.error("IOException");
     logger.error(ioe);
       }
    }
    */

    public static String renderReport(Map params, Document reportXML, String xsltFilename) {
        //used only for finding based AJAX
        //Changed XSL to xsl RCL 3/6...this is bombing

        File styleSheet = new File(ISPYContextListener.getContextPath() + "/xsl/" + xsltFilename);
        // load the transformer using JAXP
        logger.debug("Applying XSLT " + xsltFilename);
        Transformer transformer;
        try {
            transformer = new Transformer(styleSheet, params);
            Document transformedDoc = transformer.transform(reportXML);

            /*
             * right now this assumes that we will only have one XSL for CSV
             * and it checks for that as we do not want to "pretty print" the CSV, we
             * only want to spit it out as a string, or formatting gets messed up
             * we will of course want to pretty print the XHTML for the graphical reports
             * later we can change this to handle mult XSL CSVs
             * RCL
             */

            if (!xsltFilename.equals(ispyConstants.DEFAULT_XSLT_CSV_FILENAME)) {

                StringBuffer sb = new StringBuffer();
                OutputFormat format = OutputFormat.createCompactFormat();
                StringWriter sw = new StringWriter(1024);
                HTMLWriter writer = new HTMLWriter(sw, format);
                writer.write(transformedDoc);
                sb = sw.getBuffer();
                return sb.toString();

            } else {
                String csv = transformedDoc.getStringValue();
                csv.trim();
                return csv;
            }
        } catch (UnsupportedEncodingException uee) {
            logger.error("UnsupportedEncodingException");
            logger.error(uee);
        } catch (IOException ioe) {
            logger.error("IOException");
            logger.error(ioe);
        }

        return "Reporting Error";
    }
    /**
     * 
     * @param container --this is the container that you want the sample ids from
     * @return --A SampleCriteria of all the ResultsContainer sampleIds
     */
    /*
    public static SampleCriteria extractSampleIds(ResultsContainer container)throws OperationNotSupportedException{
       SampleCriteria theCriteria = new SampleCriteria();
       Collection sampleIds = new ArrayList();
       SampleViewResultsContainer svrContainer = null;
       //*
       // * These are currently the only two results containers that we have to
       // * worry about at this time, I believe.
        //
       if(container instanceof DimensionalViewContainer) {
     //Get the SampleViewResultsContainer from the DimensionalViewContainer
     DimensionalViewContainer dvContainer = (DimensionalViewContainer)container;
     svrContainer = dvContainer.getSampleViewResultsContainer();
       }else if(container instanceof SampleViewResultsContainer) {
     svrContainer = (SampleViewResultsContainer)container;
       }
       //Handle the SampleViewResultsContainers if that is what we got
       if(svrContainer!=null) {
     Collection<SampleResultset> bioSpecimen = svrContainer.getSampleResultsets();
     for(Iterator i = bioSpecimen.iterator();i.hasNext();) {
        SampleResultset sampleResultset =  (SampleResultset)i.next();
        sampleIds.add(new SampleIDDE(sampleResultset.getSampleIDDE().getValueObject()));
     }
       }else {
     throw new OperationNotSupportedException("We are not able to able to extract SampleIds from: "+container.getClass());
       }
       //Drop the sampleIds into the SampleCriteria
       theCriteria.setSampleIDs(sampleIds);
       return theCriteria;
    }
    */

    /**
     * will recurse through the compound query adding the SampleCriteria to each
     * of the associated queries.
     *  
     * @param query
     * @param sampleCriteria
     */
    /*
    public static Queriable addSampleCriteriaToCompoundQuery(Queriable query, SampleCriteria sampleCriteria, String resultSetName) {
       if(query!=null) {
     if(query instanceof CompoundQuery) {
        CompoundQuery newQuery = (CompoundQuery)query;
        try {
           newQuery.setLeftQuery(addSampleCriteriaToCompoundQuery(newQuery.getLeftQuery(), sampleCriteria, resultSetName));
           newQuery.setRightQuery(addSampleCriteriaToCompoundQuery(newQuery.getRightQuery(), sampleCriteria, resultSetName));
        }catch(Exception e) {
           logger.error(e);
        }
     }else {
        Query newQuery = (Query)query;
        newQuery.setQueryName("("+newQuery.getQueryName()+" AND "+resultSetName+")");
        newQuery.setSampleIDCrit(sampleCriteria);
        return newQuery;
     }
         
       }
       return query;
    }
    */

    /**
     * This is used to take the RefineQueryForm "filter_string" and create a 
     * list from the comma seperated tokens contained in the string. It also
     * removes any unacceptable characters and creates an acceptable string...
     * In truth it is utilizing the MoreStringUtils class to clean the strings.
     * @param filterParams
     */
    private Map processFilterParamMap(Map filterParams) {
        String test = "";
        List tokens = null;
        //String unallowableCharacters = " <>!:\"@#\\$%^&*()-+=/{}[]|?~`";
        String unallowableCharacters = " <>!\"@#\\$%^&*()+=/{}[]|?~`";
        if (filterParams != null && filterParams.containsKey("filter_string")) {
            //tokenize the string
            StringTokenizer tokenizer = new StringTokenizer((String) filterParams.get("filter_string"), ",", false);
            tokens = new ArrayList();
            while (tokenizer.hasMoreTokens()) {
                String cleanToken = MoreStringUtils.cleanString(unallowableCharacters, tokenizer.nextToken());
                cleanToken = cleanToken.toUpperCase();
                tokens.add(cleanToken);
            }
            filterParams.put("filter_string", tokens);
        }
        return filterParams;

    }

    /**
     * This will verify that the desired suffix is not already in the report
     * @param oldQueryName
     * @param suffix
     * @return
     */
    private String nameFilterQuery(String oldQueryName, String suffix) {
        String newQueryName;
        if (oldQueryName.lastIndexOf(suffix) < 0) {
            newQueryName = oldQueryName + suffix;
        } else {
            newQueryName = oldQueryName;
        }
        return newQueryName;
    }

}