Changeset 1458


Ignore:
Timestamp:
Jan 31, 2011, 8:16:03 PM (6 years ago)
Author:
robert@…
Message:
  • Implemented a cache for module rest calls, to increase performance (see moduleCommunicationService)
  • Implemented searching in module data.
Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/query/AdvancedQueryController.groovy

    r1456 r1458  
    11package dbnp.query
     2import dbnp.modules.*
     3import org.dbnp.gdt.*
    24
    35// TODO: Make use of the searchable-plugin possibilities instead of querying the database directly
     
    911 */
    1012class AdvancedQueryController {
     13        def moduleCommunicationService;
     14       
    1115        def entitiesToSearchFor = [ 'Study': 'Studies', 'Sample': 'Samples']
    1216    def index = {
     
    5660                def fields = [:];
    5761               
     62                // Retrieve all local search fields
    5863                getEntities().each {
    5964                        def entity = getEntity( 'dbnp.studycapturing.' + it );
     
    6671                               
    6772                                fields[ it ] = fieldNames.sort { a, b -> a[0].toUpperCase() + a[1..-1] <=> b[0].toUpperCase() + b[1..-1] };
     73                        }
     74                }
     75               
     76                // Loop through all modules and check which fields are searchable
     77                // Right now, we just combine the results for different entities
     78                AssayModule.list().each { module ->
     79                        def callUrl = module.url + '/rest/getQueryableFields'
     80                        try {
     81                                def json = moduleCommunicationService.callModuleRestMethodJSON( module.url, callUrl );
     82                                def moduleFields = [];
     83                                entitiesToSearchFor.each { entity ->                                   
     84                                        if( json[ entity.key ] ) {
     85                                                json[ entity.key ].each { field ->
     86                                                        moduleFields << field.toString();
     87                                                }
     88                                        }
     89                                }
     90                               
     91                                // Remove 'module' from module name
     92                                def moduleName = module.name.replace( 'module', '' ).trim()
     93                               
     94                                fields[ moduleName ] = moduleFields.unique();
     95                        } catch( Exception e ) {
     96                                log.error( "Error while retrieving queryable fields from " + module.name + ": " + e.getMessage() )
    6897                        }
    6998                }
  • trunk/grails-app/services/dbnp/modules/ModuleCommunicationService.groovy

    r1455 r1458  
    2020
    2121class ModuleCommunicationService implements Serializable {
    22     boolean transactional = false
     22        boolean transactional = false
    2323        def authenticationService
    2424        def moduleNotificationService
    25        
    26     /**
    27      * Sends a notification to assay modules that some part of a study has changed.
    28      *
    29      * Only modules that have the notify flag set to true will be notified. They will be notified on the URL
    30      *
    31      * [moduleUrl]/rest/notifyStudyChange?studyToken=abc
    32      *
    33      * Errors that occur when calling this URL are ignored. The module itself is responsible of
    34      * maintaining a synchronized state.
    35      *
    36      * @param study
    37      * @return
    38      */
     25
     26        /**
     27         * Cache containing the contents of different URLs. These urls are
     28         * saved per user, since the data could be different for different users.
     29         */
     30        def cache = [:]
     31
     32        /**
     33         * Number of seconds to save the data in cache
     34         */
     35        def numberOfSecondsInCache = 10 * 60;
     36
     37        /**
     38         * Sends a notification to assay modules that some part of a study has changed.
     39         *
     40         * Only modules that have the notify flag set to true will be notified. They will be notified on the URL
     41         *
     42         * [moduleUrl]/rest/notifyStudyChange?studyToken=abc
     43         *
     44         * Errors that occur when calling this URL are ignored. The module itself is responsible of
     45         * maintaining a synchronized state.
     46         *
     47         * @param study
     48         * @return
     49         */
    3950        def invalidateStudy( Study study ) {
    4051                moduleNotificationService.invalidateStudy( study );
    41     }
    42        
     52        }
     53
    4354        /**
    4455         * Checks whether a specific method on a module is reachable and returns a SC_OK response code.
     
    5566                try {
    5667                        return connection.responseCode == HttpServletResponse.SC_OK
    57                 } catch(e) { 
    58                         return false 
     68                } catch(e) {
     69                        return false
    5970                }
    6071        }
    61        
     72
    6273        /**
    6374         * Calls a rest method on a module
     
    6879         */
    6980        def callModuleRestMethodJSON( consumer, restUrl ) throws Exception {
    70                 // create a random session token that will be used to allow to module to
    71                 // sync with gscf prior to presenting the measurement data
    72                 def sessionToken = UUID.randomUUID().toString()
    73 
    7481                if (!authenticationService.isLoggedIn()) {
    7582                        // should not happen because we can only get here when a user is
     
    7784                        throw new Exception('User is not logged in.')
    7885                }
     86
     87                // Check whether the url is present in cache
     88                def cacheData = retrieveFromCache( restUrl );
     89                if( cacheData && cacheData[ "success" ] )
     90                        return cacheData[ "contents" ];
     91                else if( cacheData && !cacheData[ "success" ] )
     92                        throw new Exception( "Error while fetching data from " + restUrl + " (from cache): " + cacheData[ "error" ] )
     93
     94                // create a random session token that will be used to allow to module to
     95                // sync with gscf prior to presenting the measurement data
     96                def sessionToken = UUID.randomUUID().toString()
    7997
    8098                // put the session token to work
     
    90108                        url += '?sessionToken=' + sessionToken
    91109                }
    92                
     110
    93111                // Perform a call to the url
    94112                def restResponse
    95113                try {
    96114                        def textResponse = url.toURL().getText()
     115                        println "GSCF call to " + consumer + " URL: " + url
     116                        println "GSCF response: " + textResponse
    97117                        restResponse = JSON.parse( textResponse )
    98118                } catch (Exception e) {
     119                        storeErrorInCache( restUrl, e.getMessage() );
    99120                        throw new Exception( "An error occurred while fetching " + url + ".", e )
    100121                } finally {
     
    102123                        authenticationService.logOffRemotely(consumer, sessionToken)
    103124                }
     125
     126                // Store the response in cache
     127                storeInCache( restUrl, restResponse );
    104128               
    105129                return restResponse
    106130        }
     131
     132        /**
     133         * Checks whether a specific url exists in cache
     134         * @param url   URL to call
     135         * @return              true if the url is present in cache
     136         */
     137        def existsInCache( url ) {
     138                return retrieveFromCache( url ) == null;
     139        }
     140
     141        /**
     142         * Retrieves the contents of a specific URL from cache
     143         * @param url   URL to call
     144         * @return              JSON object with the contents of the URL or null if the url doesn't exist in cache
     145         */
     146        def retrieveFromCache( url ) {
     147                def user = authenticationService.getLoggedInUser();
     148                def userId = user ? user.id : -1;
     149
     150                if( cache[ userId ] && cache[ userId ][ url ] && ( System.currentTimeMillis() - cache[ userId ][ url ][ "timestamp" ] ) < numberOfSecondsInCache * 1000 ) {
     151                        return cache[ userId ][ url ];
     152                } else {
     153                        return null;
     154                }
     155        }
     156
     157        /**
     158         * Store the retrieved contents from a url in cache
     159         * @param url           URL that has been called
     160         * @param contents      Contents of the URL
     161         */
     162        def storeInCache( url, contents ) {
     163                def user = authenticationService.getLoggedInUser();
     164                def userId = user ? user.id : -1;
     165
     166                if( !cache[ userId ] )
     167                        cache[ userId ] = [:]
     168
     169                cache[ userId ][ url ] = [
     170                        "timestamp": System.currentTimeMillis(),
     171                        "success": true,
     172                        "contents": contents
     173                ];
     174        }
     175       
     176        /**
     177        * Store the retrieved error from a url in cache
     178        * @param url            URL that has been called
     179        * @param contents       Contents of the URL
     180        */
     181   def storeErrorInCache( url, error ) {
     182           def user = authenticationService.getLoggedInUser();
     183           def userId = user ? user.id : -1;
     184
     185           if( !cache[ userId ] )
     186                   cache[ userId ] = [:]
     187
     188           cache[ userId ][ url ] = [
     189                   "timestamp": System.currentTimeMillis(),
     190                   "success": false,
     191                   "error": error
     192           ];
     193   }
     194
    107195}
  • trunk/grails-app/views/advancedQuery/sampleresults.gsp

    r1430 r1458  
    2727</p>
    2828
     29
    2930<g:if test="${search.getNumResults() > 0}">
    3031
     
    3233                <thead>
    3334                <tr>
    34                         <th colspan="2"></th>
    3535                        <th>Study</th>
    3636                        <th>Name</th>
  • trunk/grails-app/views/advancedQuery/studyresults.gsp

    r1430 r1458  
    2626        resulted in ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">study</g:if><g:else>studies</g:else>.
    2727</p>
    28 
    2928<g:if test="${search.getNumResults() > 0}">
    3029
  • trunk/grails-app/views/user/search.gsp

    r1430 r1458  
    6565        <g:if test='${searched}'>
    6666
    67 <%
    68 def queryParams = [username: username, enabled: enabled, accountExpired: accountExpired, accountLocked: accountLocked, passwordExpired: passwordExpired]
    69 %>
     67        <%
     68        def queryParams = [username: username, enabled: enabled, accountExpired: accountExpired, accountLocked: accountLocked, passwordExpired: passwordExpired]
     69        %>
    7070
    7171        <div class="list">
  • trunk/src/groovy/dbnp/query/Criterion.groovy

    r1457 r1458  
    2525
    2626        /**
    27          * Checks if the given object (with template) that satisfies the given criterion.
    28          *
    29          * @param entity                Entity to check for criterion satisfaction. Should be a child of template entity
     27         * Retrieves the correct value for this criterion in the given object (with template)
     28         *
     29         * @param entity                Entity to check for value. Should be a child of template entity
    3030         * @param criterion     Criterion to match on
    31          * @return                      True iff there the entity satisfies the given criterion.
    32          */
    33         public boolean matchOne( TemplateEntity entity ) {
     31         * @return                      Value of the given field or null if the field doesn't exist
     32         */
     33        public def getFieldValue( TemplateEntity entity ) {
     34                if( entity == null )
     35                        return null;
     36
    3437                try {
    3538                        def fieldValue
     
    4043                        }
    4144
    42                         return this.match( fieldValue );
     45                        return fieldValue
    4346                } catch( Exception e ) {
    4447                        // An exception occurs if the given field doesn't exist. In that case, this criterion will fail.
    4548                        // TODO: Maybe give the user a choice whether he want's to include these studies or not
    46                         return false;
    47                 }
     49                        return null;
     50                }
     51        }
     52
     53        /**
     54         * Checks if the given object (with template) that satisfies the given criterion.
     55         *
     56         * @param entity                Entity to check for criterion satisfaction. Should be a child of template entity
     57         * @param criterion     Criterion to match on
     58         * @return                      True iff there the entity satisfies the given criterion.
     59         */
     60        public boolean matchEntity( TemplateEntity entity ) {
     61                def fieldValue = this.getFieldValue( entity );
     62
     63                // Null is returned, the given field doesn't exist. In that case, this criterion will fail.
     64                // TODO: Maybe give the user a choice whether he want's to include these studies or not
     65                if( fieldValue == null )
     66                        return false;
     67
     68                return this.match( fieldValue );
    4869        }
    4970
     
    5576         * @return                              True iff there is any entity in the list that satisfies the given criterion.
    5677         */
    57         public boolean matchAny( List entityList ) {
     78        public boolean matchAnyEntity( List<TemplateEntity> entityList ) {
    5879                for( entity in entityList ) {
    59                         if( matchOne( entity ) )
     80                        if( matchOneEntity( entity ) )
    6081                                return true;
    6182                }
     
    7091         * @return                              True iff all entities satisfy the given criterion.
    7192         */
     93        public boolean matchAllEntities( List<TemplateEntity> entityList ) {
     94                for( entity in entityList ) {
     95                        if( !matchOneEntity( entity ) )
     96                                return false;
     97                }
     98                return true;
     99        }
     100
     101        /**
     102         * Checks for all values in the given List, if there is any value that satisfies the given criterion.
     103         *
     104         * @param entityList            List with values.
     105         * @param criterion             Criterion to match on
     106         * @return                              True iff there is any value in the list that satisfies the given criterion.
     107         */
     108        public boolean matchAny( List valueList ) {
     109                for( value in valueList ) {
     110                        if( match( value ) )
     111                                return true;
     112                }
     113                return false;
     114        }
     115
     116        /**
     117         * Checks for all values in the given List, if all values satisfy the given criterion.
     118         *
     119         * @param entityList            List with values.
     120         * @param criterion             Criterion to match on
     121         * @return                              True iff all values satisfy the given criterion.
     122         */
    72123        public boolean matchAll( List entityList ) {
    73                 for( entity in entityList ) {
    74                         if( !matchOne( entity ) )
     124                for( value in valueList ) {
     125                        if( !match( value ) )
    75126                                return false;
    76127                }
     
    87138                if( fieldValue == null )
    88139                        return false;
    89                        
     140
    90141                def classname = fieldValue.class.getName();
    91142                classname = classname[classname.lastIndexOf( '.' ) + 1..-1].toLowerCase();
    92                
     143
    93144                println "Match " + fieldValue + " of class " + classname + " with " + this
    94                
     145
    95146                try {
    96147                        switch( classname ) {
     
    152203                        Date dateCriterion = new SimpleDateFormat( "yyyy-MM-dd" ).parse( value );
    153204                        Date fieldDate = new Date( fieldValue.getTime() );
    154                        
     205
    155206                        // Clear time in order to just compare dates
    156207                        dateCriterion.clearTime();
    157208                        fieldDate.clearTime();
    158                        
     209
    159210                        return compareValues( fieldDate, this.operator, dateCriterion )
    160211                } catch( Exception e ) {
     
    232283
    233284                        // Numbers are taken to be seconds, if a non-numeric value is given, try to parse it
    234                         if( value.toString().isNumber() ) {
     285                        if( value.toString().isLong() ) {
    235286                                rt = new RelTime( Long.parseLong( value.toString() ) );
    236287                        } else {
    237288                                rt = new RelTime( value.toString() );
    238289                        }
    239                        
     290
    240291                        return compareValues( fieldValue, this.operator, rt );
    241292                } catch( Exception e ) {
  • trunk/src/groovy/dbnp/query/SampleSearch.groovy

    r1456 r1458  
    1616
    1717import dbnp.studycapturing.*
     18import org.dbnp.gdt.*
    1819
    1920class SampleSearch extends Search {
     21       
    2022        public SampleSearch() {
    2123                this.entity = "Sample";
     
    9395                samples = filterOnAssayCriteria( samples );
    9496               
     97                samples = filterOnModuleCriteria( samples );
     98               
    9599                // Save matches
    96100                results = samples;
     
    103107         */
    104108        protected List filterOnStudyCriteria( List studies ) {
    105                 return filterEntityList( studies, getEntityCriteria( 'Study' ), { study, criterion ->
    106                         return criterion.matchOne( study );
    107                 });
     109                return filterOnTemplateEntityCriteria(studies, "Study", { study, criterion -> return criterion.getFieldValue( study ) })
    108110        }
    109111
     
    114116         */
    115117        protected List filterOnSubjectCriteria( List samples ) {
    116                 return filterEntityList( samples, getEntityCriteria( 'Subject' ), { sample, criterion ->
    117                         if( !sample.parentSubject )
    118                                 return false
    119 
    120                         return criterion.matchOne( sample.parentSubject );
    121                 });
     118                return filterOnTemplateEntityCriteria(samples, "Subject", { sample, criterion ->
     119                        return criterion.getFieldValue( sample.parentSubject );
     120                })
    122121        }
    123122
     
    128127         */
    129128        protected List filterOnSampleCriteria( List samples ) {
    130                 return filterEntityList( samples, getEntityCriteria( 'Sample' ), { sample, criterion ->
    131                         if( !sample  )
    132                                 return false
    133 
    134                         return criterion.matchOne( sample );
    135                 });
     129                return filterOnTemplateEntityCriteria(samples, "Sample", { sample, criterion ->
     130                        return criterion.getFieldValue( sample );
     131                })
    136132        }
    137133
     
    142138         */
    143139        protected List filterOnEventCriteria( List samples ) {
    144                 println "Event criteria: " + getEntityCriteria( 'Event' )
    145                 return filterEntityList( samples, getEntityCriteria( 'Event' ), { sample, criterion ->
     140                return filterOnTemplateEntityCriteria(samples, "Event", { sample, criterion ->
    146141                        if( !sample || !sample.parentEventGroup || !sample.parentEventGroup.events || sample.parentEventGroup.events.size() == 0 )
    147                                 return false
    148                
    149                         return criterion.matchAny( sample.parentEventGroup.events.toList() );
    150                 });
     142                                return null
     143
     144                        return criterion.getFieldValue( sample.parentEventGroup.events.toList() );
     145                })
    151146        }
    152147
     
    157152         */
    158153        protected List filterOnSamplingEventCriteria( List samples ) {
    159                 return filterEntityList( samples, getEntityCriteria( 'SamplingEvent' ), { sample, criterion ->
    160                         if( !sample.parentEvent )
    161                                 return false
    162 
    163                         return criterion.matchOne( sample.parentEvent );
    164                 });
    165         }
    166 
     154                return filterOnTemplateEntityCriteria(samples, "SamplingEvent", { sample, criterion ->
     155                        return criterion.getFieldValue( sample.parentEvent );
     156                })
     157        }
    167158
    168159        /**
     
    180171                // There is no sample.assays property, so we have to look for assays another way: just find
    181172                // all assays that match the criteria
    182                 def assays = filterEntityList( Assay.list(), getEntityCriteria( 'Assay' ), { assay, criterion ->
     173                def criteria = getEntityCriteria( 'Assay' );
     174                def assays = filterEntityList( Assay.list(), criteria, { assay, criterion ->
    183175                        if( !assay )
    184176                                return false
     
    190182                if( assays.size() == 0 )
    191183                        return [];
     184               
     185                // 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
     191                                return null
     192                });
    192193                       
    193194                // Now filter the samples on whether they are attached to the filtered assays
     
    208209                }
    209210        }
    210 
    211211}
  • trunk/src/groovy/dbnp/query/Search.groovy

    r1457 r1458  
    1616package dbnp.query
    1717
     18import groovy.lang.Closure;
     19
    1820import java.text.SimpleDateFormat
     21import java.util.List;
     22
     23import org.springframework.context.ApplicationContext
     24import org.codehaus.groovy.grails.commons.ApplicationHolder;
     25
    1926import org.dbnp.gdt.*
    2027
     
    2431        protected List criteria;
    2532        protected List results;
     33        protected Map resultFields = [:];
    2634
    2735        public List getCriteria() { return criteria; }
     
    3038        public List getResults() { return results; }
    3139        public void setResults( List r ) { results = r; }
     40       
     41        public Map getResultFields() { return resultFields; }
     42        public void setResultFields( Map r ) { resultFields = r; }
    3243
    3344        /**
     
    156167
    157168        }
     169       
     170       
     171        /**
     172         * Filters the given list of studies on the study criteria
     173         * @param studies               Original list of studies
     174         * @param entity                Name of the entity to check the criteria for
     175         * @param valueCallback Callback having a study and criterion as input, returning the value of the field to check on
     176         * @return                              List with all studies that match the Criteria
     177         */
     178        protected List filterOnTemplateEntityCriteria( List studies, String entityName, Closure valueCallback ) {
     179                def criteria = getEntityCriteria( entityName );
     180                def checkCallback = { study, criterion ->
     181                        def value = valueCallback( study, criterion );
     182                       
     183                        if( value == null )
     184                                return false
     185                        if( value instanceof Collection ) {
     186                                return criterion.matchAny( value )
     187                        } else {
     188                                return criterion.match( value );
     189                        }
     190                }
     191
     192                // Save the value of this entity for later use
     193                saveResultFields( studies, criteria, valueCallback );
     194
     195                return filterEntityList( studies, criteria, checkCallback);
     196        }
     197
     198        /**
     199        * Filters the given list of entities on the module criteria
     200        * @param entities       Original list of entities. Entities should expose a giveUUID() method to give the token.
     201        * @return                       List with all entities that match the module criteria
     202        */
     203        protected List filterOnModuleCriteria( List entities ) {
     204                // An empty list can't be filtered more than is has been now
     205                if( !entities || entities.size() == 0 )
     206                        return [];
     207                       
     208                // Determine the moduleCommunicationService
     209                ApplicationContext ctx = (ApplicationContext)ApplicationHolder.getApplication().getMainContext();
     210                def moduleCommunicationService = ctx.getBean("moduleCommunicationService");
     211                       
     212                // Loop through all modules and check whether criteria have been given
     213                // for that module
     214                AssayModule.list().each { module ->
     215                        // Remove 'module' from module name
     216                        def moduleName = module.name.replace( 'module', '' ).trim()
     217                        def moduleCriteria = getEntityCriteria( moduleName );
     218                       
     219                        if( moduleCriteria && moduleCriteria.size() > 0 ) {
     220                                println "Filter " + entities.size() + " entities on " + module.name + " criteria: " + moduleCriteria.size();
     221
     222                                // Retrieve the data from the module
     223                                def tokens = entities.collect { it.giveUUID() }.unique();
     224                                def fields = moduleCriteria.collect { it.field }.unique();
     225                               
     226                                def callUrl = module.url + '/rest/getQueryableFieldData?entity=' + this.entity
     227                                tokens.sort().each { callUrl += "&tokens=" + it.encodeAsURL() }
     228                                fields.sort().each { callUrl += "&fields=" + it.encodeAsURL() }
     229                               
     230                                try {
     231                                        def json = moduleCommunicationService.callModuleRestMethodJSON( module.url, callUrl );
     232
     233                                        // The data has been retrieved. Now walk through all criteria to filter the samples
     234                                        entities = filterEntityList( entities, moduleCriteria, { entity, criterion ->
     235                                                // Find the value of the field in this sample. That value is still in the
     236                                                // JSON object
     237                                                def token = entity.giveUUID()
     238                                                if( !json[ token ] || json[ token ][ criterion.field ] == null )
     239                                                        return false;
     240
     241                                                // Check whether a list or string is given
     242                                                def value = json[ token ][ criterion.field ];
     243                                               
     244                                                // Save the value of this entity for later use
     245                                                saveResultField( entity.id, criterion.field, value )
     246
     247                                                if( !( value instanceof Collection ) ) {
     248                                                        value = [ value ];
     249                                                }
     250                                               
     251                                                // Loop through all values and match any
     252                                                for( val in value ) {
     253                                                        // Convert numbers to a long or double in order to process them correctly
     254                                                        val = val.toString();
     255                                                        if( val.isLong() ) {
     256                                                                val = Long.parseLong( val );
     257                                                        } else if( val.isDouble() ) {
     258                                                                val = Double.parseDouble( val );
     259                                                        }
     260                                                       
     261                                                        if( criterion.match( val ) )
     262                                                                return true;
     263                                                }
     264                                               
     265                                                return false;
     266                                        });
     267                                                                               
     268                                } catch( Exception e ) {
     269                                        println( "Error while retrieving data from " + module.name + ": " + e.getMessage() )
     270                                }
     271                        }
     272                }
     273               
     274                return entities;
     275        }
     276       
     277        /**
     278         * Saves data about template entities to use later on. This data is copied to a special
     279         * structure to make it compatible with data fetched from other modules. Ses also saveResultField() method
     280         * @param entities                      List of template entities to find data in
     281         * @param criteria                      Criteria to search for
     282         * @param valueCallback         Callback to retrieve a specific field from the entity
     283         */
     284        protected void saveResultFields( entities, criteria, valueCallback ) {
     285                for( criterion in criteria ) {
     286                        for( entity in entities ) {
     287                                saveResultField( entity.id, criterion.field, valueCallback( entity, criterion ) )
     288                        }
     289                }
     290        }
     291
     292       
     293        /**
     294         * Saves a specific field of an object to use later on. Especially useful when looking up data from other modules.
     295         * @param id            ID of the object
     296         * @param fieldName     Field name that has been searched
     297         * @param value         Value of the field
     298         */
     299        protected void saveResultField( id, fieldName, value ) {
     300                if( resultFields[ id ] == null )
     301                        resultFields[ id ] = [:]
     302               
     303                resultFields[ id ][ fieldName ] = value;
     304        }
    158305}
  • trunk/src/groovy/dbnp/query/StudySearch.groovy

    r1456 r1458  
    1515package dbnp.query
    1616
     17import java.util.List;
     18
    1719import dbnp.studycapturing.*
     20import org.dbnp.gdt.*
    1821
    1922class StudySearch extends Search {
     
    7376                studies = filterOnAssayCriteria( studies );
    7477
     78                studies = filterOnModuleCriteria( studies );
     79               
    7580                // Save matches
    7681                results = studies;
    7782        }
    78 
     83       
    7984        /**
    8085         * Filters the given list of studies on the study criteria
    8186         * @param studies       Original list of studies
    82          * @return                      List with all studies that match the Study-criteria
     87         * @return                      List with all studies that match the Study criteria
    8388         */
    8489        protected List filterOnStudyCriteria( List studies ) {
    85                 return filterEntityList( studies, getEntityCriteria( 'Study' ), { study, criterion ->
    86                         return criterion.matchOne( study );
    87                 });
     90                return filterOnTemplateEntityCriteria(studies, "Study", { study, criterion -> return criterion.getFieldValue( study ) })
    8891        }
    8992
     
    9497         */
    9598        protected List filterOnSubjectCriteria( List studies ) {
    96                 return filterEntityList( studies, getEntityCriteria( 'Subject' ), { study, criterion ->
    97                         if( !study.subjects?.size() )
    98                                 return false
    99 
    100                         return criterion.matchAny( study.subjects );
    101                 });
     99                return filterOnTemplateEntityCriteria(studies, "Subject", { study, criterion ->
     100                        return study.subjects?.collect { criterion.getFieldValue( it ); }
     101                })
    102102        }
    103103
     
    108108         */
    109109        protected List filterOnSampleCriteria( List studies ) {
    110                 return filterEntityList( studies, getEntityCriteria( 'Sample' ), { study, criterion ->
    111                         if( !study.samples?.size() )
    112                                 return false
    113 
    114                         return criterion.matchAny( study.samples );
    115                 });
     110                return filterOnTemplateEntityCriteria(studies, "Sample", { study, criterion ->
     111                        return study.samples?.collect { criterion.getFieldValue( it ); }
     112                })
    116113        }
    117114
     
    122119         */
    123120        protected List filterOnEventCriteria( List studies ) {
    124                 return filterEntityList( studies, getEntityCriteria( 'Event' ), { study, criterion ->
    125                         if( !study.events?.size() )
    126                                 return false
    127 
    128                         return criterion.matchAny( study.events );
    129                 });
     121                return filterOnTemplateEntityCriteria(studies, "Event", { study, criterion ->
     122                        return study.events?.collect { criterion.getFieldValue( it ); }
     123                })
    130124        }
    131125       
     
    136130        */
    137131   protected List filterOnSamplingEventCriteria( List studies ) {
    138            return filterEntityList( studies, getEntityCriteria( 'SamplingEvent' ), { study, criterion ->
    139                    if( !study.samplingEvents?.size() )
    140                            return false
    141 
    142                         return criterion.matchAny( study.samplingEvents );
    143            });
     132                return filterOnTemplateEntityCriteria(studies, "SamplingEvent", { study, criterion ->
     133                        return study.samplingEvents?.collect { criterion.getFieldValue( it ); }
     134                })
    144135   }
    145 
    146136       
    147137        /**
     
    151141         */
    152142        protected List filterOnAssayCriteria( List studies ) {
    153                 return filterEntityList( studies, getEntityCriteria( 'Assay' ), { study, criterion ->
    154                         if( !study.assays?.size() )
    155                                 return false
    156 
    157                         return criterion.matchAny( study.assays );
    158                 });
     143                return filterOnTemplateEntityCriteria(studies, "Assay", { study, criterion ->
     144                        return study.assays?.collect { criterion.getFieldValue( it ); }
     145                })
    159146        }
    160147}
Note: See TracChangeset for help on using the changeset viewer.