Changeset 1482 for trunk/src


Ignore:
Timestamp:
Feb 2, 2011, 4:40:22 PM (9 years ago)
Author:
robert@…
Message:

Implemented saving of queries

Location:
trunk/src/groovy/dbnp/query
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/groovy/dbnp/query/Criterion.groovy

    r1458 r1482  
    33import java.text.SimpleDateFormat
    44import org.dbnp.gdt.*
     5import org.apache.commons.logging.LogFactory;
    56
    67/**
     
    1011 */
    1112enum Operator {
    12         equals, contains, gte, gt, lte, lt
     13        equals( "=" ), contains( "contains" ), gte( ">="), gt( ">" ), lte( "<=" ), lt( "<" ), insearch( "in" )
     14        Operator(String name) { this.name = name }
     15        private final String name;
     16        public String toString() { return name }
    1317}
    1418
     
    1923 */
    2024class Criterion {
     25        private static final log = LogFactory.getLog(this);
    2126        public String entity
    2227        public String field
     
    2530
    2631        /**
     32         * Retrieves a combination of the entity and field
     33         * @return
     34         */
     35        public String entityField() {
     36                return entity.toString() + ( field ? "." + field.toString() : "" );
     37        }
     38       
     39        /**
    2740         * Retrieves the correct value for this criterion in the given object (with template)
    2841         *
    2942         * @param entity                Entity to check for value. Should be a child of template entity
    30          * @param criterion     Criterion to match on
    31          * @return                      Value of the given field or null if the field doesn't exist
     43         * @param criterion             Criterion to match on
     44         * @return                              Value of the given field or null if the field doesn't exist
    3245         */
    3346        public def getFieldValue( TemplateEntity entity ) {
     
    3750                try {
    3851                        def fieldValue
    39                         if( field == "Template" ) {
     52                        if( !field ) {
     53                                fieldValue = entity
     54                        } else if( field == "Template" ) {
    4055                                fieldValue = entity.template?.name
    4156                        } else {
     
    138153                if( fieldValue == null )
    139154                        return false;
    140 
     155               
     156                // in-search criteria have to be handled separately
     157                if( this.operator == Operator.insearch ) {
     158                        return this.value?.getResults()?.contains( fieldValue );
     159                }       
     160               
     161                // Other criteria are handled based on the class of the value given.
    141162                def classname = fieldValue.class.getName();
    142163                classname = classname[classname.lastIndexOf( '.' ) + 1..-1].toLowerCase();
    143 
    144                 println "Match " + fieldValue + " of class " + classname + " with " + this
    145164
    146165                try {
     
    185204                                return fieldValue <= criterionValue;
    186205                        case Operator.contains:
    187                                 return fieldValue.contains( criterionValue );
     206                                // Contains operator can only be used on string values
     207                                return fieldValue.toString().contains( criterionValue.toString() );
    188208                        case Operator.equals:
    189209                        default:
     
    295315                }
    296316        }
     317       
     318        public static Operator parseOperator( String name ) throws Exception {
     319                switch( name.trim() ) {
     320                        case "=": 
     321                        case "equals":          return Operator.equals;
     322                        case "contains":        return Operator.contains;
     323                        case ">=":
     324                        case "gte":                     return Operator.gte;
     325                        case ">":
     326                        case "gt":                      return Operator.gt;
     327                        case "<=":
     328                        case "lte":                     return Operator.lte;
     329                        case "<":
     330                        case "lt":                      return Operator.lt;
     331                        case "in":                      return Operator.insearch;
     332                        default:
     333                                throw new Exception( "Operator not found" );
     334                }
     335        }
    297336
    298337        public String toString() {
    299                 return "[Criterion " + entity + "." + field + " " + operator + " " + value + "]";
     338                return "[Criterion " + entityField() + " " + operator + " " + value + "]";
     339        }
     340       
     341        public boolean equals( Object o ) {
     342                if( o == null )
     343                        return false;
     344               
     345                if( !( o instanceof Criterion ) )
     346                        return false;
     347                       
     348                Criterion otherCriterion = (Criterion) o;
     349                return  this.entity == otherCriterion.entity &&
     350                                this.field == otherCriterion.field &&
     351                                this.operator == otherCriterion.operator &&
     352                                this.value == otherCriterion.value;
    300353        }
    301354}
  • trunk/src/groovy/dbnp/query/SampleSearch.groovy

    r1458 r1482  
    1515package dbnp.query
    1616
     17import java.util.Map;
     18
    1719import dbnp.studycapturing.*
    1820import org.dbnp.gdt.*
     21import org.apache.commons.logging.LogFactory;
    1922
    2023class SampleSearch extends Search {
     24        private static final log = LogFactory.getLog(this);
    2125       
    2226        public SampleSearch() {
     27                super();
     28                               
    2329                this.entity = "Sample";
    2430        }
     
    5763        @Override
    5864        void execute() {
    59                 // TODO: check for authorization for these studies?
     65                super.execute();
    6066
    6167                // If no criteria are found, return all samples
    6268                if( !criteria || criteria.size() == 0 ) {
    63                         results = Sample.list();
     69                        results = Sample.list().findAll { it.parent?.canRead( this.user ) };
    6470                        return;
    6571                }
     
    7278                def samples = []
    7379                if( getEntityCriteria( 'Study' ).size() > 0 ) {
    74                         def studies = Study.findAll();
    75                        
     80                        def studies = Study.findAll().findAll { it.canRead( this.user ) };
     81
    7682                        studies = filterOnStudyCriteria( studies );
    77                        
     83
    7884                        if( studies.size() == 0 ) {
    7985                                results = [];
    8086                                return;
    8187                        }
    82                        
     88
    8389                        def c = Sample.createCriteria()
    8490                        samples = c.list {
    8591                                'in'( 'parent', studies )
    8692                        }
     93
     94                        // Save data about the resulting studies in the
     95                        // result fields array. The data that is now in the array
     96                        // is saved based on the study id, not based on the sample id
     97                        clearResultFields();
     98                        saveResultFields( samples, getEntityCriteria( "Study" ), { sample, criterion ->
     99                                return criterion.getFieldValue( sample.parent );
     100                        });
    87101                } else {
    88                         samples = Sample.findAll()
     102                        samples = Sample.findAll().findAll { it.parent?.canRead( this.user ) }
    89103                }
    90104
     
    94108                samples = filterOnSamplingEventCriteria( samples );
    95109                samples = filterOnAssayCriteria( samples );
    96                
     110
    97111                samples = filterOnModuleCriteria( samples );
    98                
     112
    99113                // Save matches
    100114                results = samples;
     
    168182                if( getEntityCriteria( 'Assay' ).size() == 0 )
    169183                        return samples
    170                        
     184
    171185                // There is no sample.assays property, so we have to look for assays another way: just find
    172186                // all assays that match the criteria
     
    178192                        return criterion.matchOne( assay );
    179193                });
    180                
     194
    181195                // If no assays match these criteria, then no samples will match either
    182196                if( assays.size() == 0 )
    183197                        return [];
    184                
     198
    185199                // Save sample data for later use
    186                 saveResultFields( samples, criteria, { sample, criterion -> 
    187                          def sampleAssays = Assay.findByStudy( sample.parent ).findAll { it.samples?.contains( sample ) };
    188                          if( sampleAssays && sampleAssays.size() > 0 )
    189                                 return sampleAssays.collect( criterion.getFieldValue( it ) )
    190                         else 
     200                saveResultFields( samples, criteria, { sample, criterion ->
     201                        def sampleAssays = Assay.findByStudy( sample.parent ).findAll { it.samples?.contains( sample ) };
     202                        if( sampleAssays && sampleAssays.size() > 0 )
     203                                return sampleAssays.collect( criterion.getFieldValue( it ) )
     204                        else
    191205                                return null
    192206                });
    193                        
     207
    194208                // Now filter the samples on whether they are attached to the filtered assays
    195209                return samples.findAll { sample ->
    196210                        if( !sample.parent )
    197211                                return false;
    198                        
     212
    199213                        def studyAssays = assays.findAll { it.parent.equals( sample.parent ); }
    200                        
    201                         // See if this sample is present in any of the matching assays. If so, 
     214
     215                        // See if this sample is present in any of the matching assays. If so,
    202216                        // this sample matches the criteria
    203217                        for( def assay in studyAssays ) {
    204                                 if( assay.samples?.contains( sample ) ) 
     218                                if( assay.samples?.contains( sample ) )
    205219                                        return true;
    206220                        }
    207                        
     221
    208222                        return false;
    209223                }
    210224        }
     225
     226        /**
     227         * Returns the saved field data that could be shown on screen. This means, the data
     228         * is filtered to show only data of the query results. Also, the study title and sample
     229         * name are filtered out, in order to be able to show all data on the screen without
     230         * checking further
     231         *
     232         * @return      Map with the entity id as a key, and a field-value map as value
     233         */
     234        public Map getShowableResultFields() {
     235                Map showableFields = super.getShowableResultFields()
     236                showableFields.each { sampleElement ->
     237                        sampleElement.value = sampleElement.value.findAll { fieldElement ->
     238                                fieldElement.key != "Study title" && fieldElement.key != "Sample name"
     239                        }
     240                }
     241        }
    211242}
  • trunk/src/groovy/dbnp/query/Search.groovy

    r1478 r1482  
    1616package dbnp.query
    1717
     18import dbnp.authentication.SecUser
    1819import groovy.lang.Closure;
    1920
     
    2223
    2324import org.springframework.context.ApplicationContext
     25import org.springframework.web.context.request.RequestContextHolder;
    2426import org.codehaus.groovy.grails.commons.ApplicationHolder;
    2527
     
    2830class Search {
    2931        public String entity;
     32        public SecUser user;
     33        public Date executionDate;
     34        public int id;  // Is only used when this query is saved in session
    3035
    3136        protected List criteria;
     
    4247        public void setResultFields( Map r ) { resultFields = r; }
    4348
     49<<<<<<< .mine
     50        public Search() {
     51                ApplicationContext ctx = (ApplicationContext)ApplicationHolder.getApplication().getMainContext();
     52                def authenticationService = ctx.getBean("authenticationService");
     53                def sessionUser = authenticationService.getLoggedInUser();
     54               
     55                if( sessionUser )
     56                        this.user = sessionUser;
     57                else
     58                        this.user = null
     59        }
     60       
     61=======
     62>>>>>>> .r1481
    4463        /**
    4564         * Returns the number of results found by this search
     
    6887         * subclasses searching for a specific entity
    6988         */
    70         public void execute() {}
     89        public void execute() {
     90                this.executionDate = new Date();
     91        }
    7192
    7293        /**
     
    146167                                        return Boolean.valueOf( value )
    147168                                } catch( Exception e ) {
    148                                         println e.getMessage();
    149169                                        return value.toString();
    150170                                }
     
    178198        protected List filterOnTemplateEntityCriteria( List studies, String entityName, Closure valueCallback ) {
    179199                def criteria = getEntityCriteria( entityName );
     200               
    180201                def checkCallback = { study, criterion ->
    181202                        def value = valueCallback( study, criterion );
     
    192213                // Save the value of this entity for later use
    193214                saveResultFields( studies, criteria, valueCallback );
    194 
     215               
    195216                return filterEntityList( studies, criteria, checkCallback);
    196217        }
     
    207228                       
    208229                // Determine the moduleCommunicationService
    209                 def ctx = ApplicationHolder.getApplication().getMainContext();
     230                def ctx = (ApplicationContext)ApplicationHolder.getApplication().getMainContext();
    210231                def moduleCommunicationService = ctx.getBean("moduleCommunicationService");
    211232                       
     
    218239                       
    219240                        if( moduleCriteria && moduleCriteria.size() > 0 ) {
    220                                 println "Filter " + entities.size() + " entities on " + module.name + " criteria: " + moduleCriteria.size();
    221 
    222241                                // Retrieve the data from the module
    223242                                def tokens = entities.collect { it.giveUUID() }.unique();
     
    243262                                               
    244263                                                // Save the value of this entity for later use
    245                                                 saveResultField( entity.id, criterion.field, value )
     264                                                saveResultField( entity.id, criterion.entity + " " + criterion.field, value )
    246265
    247266                                                if( !( value instanceof Collection ) ) {
     
    267286                                                                               
    268287                                } catch( Exception e ) {
    269                                         println( "Error while retrieving data from " + module.name + ": " + e.getMessage() )
     288                                        log.error( "Error while retrieving data from " + module.name + ": " + e.getMessage() )
    270289                                }
    271290                        }
     
    285304                for( criterion in criteria ) {
    286305                        for( entity in entities ) {
    287                                 saveResultField( entity.id, criterion.field, valueCallback( entity, criterion ) )
     306                                if( criterion.field )
     307                                        saveResultField( entity.id, criterion.entity + ' ' + criterion.field, valueCallback( entity, criterion ) )
    288308                        }
    289309                }
     
    303323                resultFields[ id ][ fieldName ] = value;
    304324        }
     325       
     326        /**
     327         * Removes all data from the result field map
     328         */
     329        protected void clearResultFields() {
     330                resultFields = [:]
     331        }
     332       
     333        /**
     334         * Returns the saved field data that could be shown on screen. This means, the data is filtered to show only data of the query results.
     335         *
     336         * Subclasses could filter out the fields they don't want to show on the result screen (e.g. because they are shown regardless of the
     337         * query.)
     338         * @return      Map with the entity id as a key, and a field-value map as value
     339         */
     340        public Map getShowableResultFields() {
     341                def resultIds = getResults()*.id;
     342                return getResultFields().findAll {
     343                        resultIds.contains( it.key )
     344                }
     345        }
     346       
     347        public String toString() {
     348                return ( this.entity ? this.entity + " search" : "Search" ) + " " + this.id
     349        }
    305350}
  • trunk/src/groovy/dbnp/query/StudySearch.groovy

    r1458 r1482  
    1616
    1717import java.util.List;
     18import java.util.Map;
    1819
    1920import dbnp.studycapturing.*
    2021import org.dbnp.gdt.*
     22import org.apache.commons.logging.LogFactory;
    2123
    2224class StudySearch extends Search {
     25        private static final log = LogFactory.getLog(this);
     26       
    2327        public StudySearch() {
     28                super();
    2429                this.entity = "Study";
    2530        }
     
    5964        @Override
    6065        void execute() {
    61                 // TODO: check for authorization for these studies?
    62                 def studies = Study.list();
     66                super.execute();
    6367
     68                def studies = Study.list().findAll { it.canRead( this.user ) };
     69               
    6470                // If no criteria are found, return all studies
    6571                if( !criteria || criteria.size() == 0 ) {
     
    7581                studies = filterOnSamplingEventCriteria( studies );
    7682                studies = filterOnAssayCriteria( studies );
    77 
     83               
    7884                studies = filterOnModuleCriteria( studies );
    7985               
     
    8187                results = studies;
    8288        }
    83        
     89
    8490        /**
    8591         * Filters the given list of studies on the study criteria
     
    97103         */
    98104        protected List filterOnSubjectCriteria( List studies ) {
    99                 return filterOnTemplateEntityCriteria(studies, "Subject", { study, criterion -> 
     105                return filterOnTemplateEntityCriteria(studies, "Subject", { study, criterion ->
    100106                        return study.subjects?.collect { criterion.getFieldValue( it ); }
    101107                })
     
    119125         */
    120126        protected List filterOnEventCriteria( List studies ) {
    121                 return filterOnTemplateEntityCriteria(studies, "Event", { study, criterion -> 
     127                return filterOnTemplateEntityCriteria(studies, "Event", { study, criterion ->
    122128                        return study.events?.collect { criterion.getFieldValue( it ); }
    123129                })
    124130        }
    125        
     131
    126132        /**
    127         * Filters the given list of studies on the sampling event criteria
    128         * @param studies        Original list of studies
    129         * @return                       List with all studies that match the event-criteria
    130         */
    131    protected List filterOnSamplingEventCriteria( List studies ) {
    132                 return filterOnTemplateEntityCriteria(studies, "SamplingEvent", { study, criterion -> 
     133         * Filters the given list of studies on the sampling event criteria
     134         * @param studies       Original list of studies
     135         * @return                      List with all studies that match the event-criteria
     136         */
     137        protected List filterOnSamplingEventCriteria( List studies ) {
     138                return filterOnTemplateEntityCriteria(studies, "SamplingEvent", { study, criterion ->
    133139                        return study.samplingEvents?.collect { criterion.getFieldValue( it ); }
    134140                })
    135    }
    136        
     141        }
     142
    137143        /**
    138144         * Filters the given list of studies on the assay criteria
     
    145151                })
    146152        }
     153
     154        /**
     155         * Returns the saved field data that could be shown on screen. This means, the data
     156         * is filtered to show only data of the query results. Also, the study title and sample
     157         * name are filtered out, in order to be able to show all data on the screen without
     158         * checking further
     159         *
     160         * @return      Map with the entity id as a key, and a field-value map as value
     161         */
     162        public Map getShowableResultFields() {
     163                Map showableFields = super.getShowableResultFields()
     164                showableFields.each { sampleElement ->
     165                        sampleElement.value = sampleElement.value.findAll { fieldElement ->
     166                                fieldElement.key != "Study title" && fieldElement.key != "Subject species"
     167                        }
     168                }
     169                return showableFields
     170        }
    147171}
Note: See TracChangeset for help on using the changeset viewer.