source: trunk/src/groovy/dbnp/query/Criterion.groovy @ 1436

Last change on this file since 1436 was 1436, checked in by robert@…, 10 years ago

Improved querying, fixed some tests and added imports of the GDT plugin

  • Property svn:keywords set to Rev Author Date
File size: 7.7 KB
Line 
1package dbnp.query
2
3import java.util.Date;
4import java.util.List;
5import java.text.SimpleDateFormat;
6
7import nl.grails.plugins.gdt.*
8
9/**
10 * Available operators for criteria
11 * @author robert
12 *
13 */
14enum Operator {
15        equals, contains, gte, gt, lte, lt
16}
17
18/**
19 * Represents a criterion to search on
20 * @author robert
21 *
22 */
23class Criterion {
24        public String entity
25        public String field
26        public Operator operator
27        public def value
28
29        /**
30         * Checks if the given object (with template) that satisfies the given criterion.
31         *
32         * @param entity                Entity to check for criterion satisfaction. Should be a child of template entity
33         * @param criterion     Criterion to match on
34         * @return                      True iff there the entity satisfies the given criterion.
35         */
36        public boolean matchOne( TemplateEntity entity ) {
37                try {
38                        def fieldValue
39                        if( field == "Template" ) {
40                                fieldValue = entity.template?.name
41                        } else {
42                                fieldValue = Search.prepare( entity.getFieldValue( field ), entity.giveFieldType( field ) )
43                        }
44
45                        return this.match( fieldValue );
46                } catch( Exception e ) {
47                        // An exception occurs if the given field doesn't exist. In that case, this criterion will fail.
48                        // TODO: Maybe give the user a choice whether he want's to include these studies or not
49                        return false;
50                }
51        }
52
53        /**
54         * Checks for all entities in the given entityList, if there is any object that satisfies the given criterion.
55         *
56         * @param entityList    List with entities. The entities should be child classes of TemplateEntity
57         * @param criterion             Criterion to match on
58         * @return                              True iff there is any entity in the list that satisfies the given criterion.
59         */
60        public boolean matchAny( List entityList ) {
61                for( entity in entityList ) {
62                        if( matchOne( entity ) )
63                                return true;
64                }
65                return false;
66        }
67
68        /**
69         * Checks for all entities in the given entityList, if all objects satisfy the given criterion.
70         *
71         * @param entityList    List with entities. The entities should be child classes of TemplateEntity
72         * @param criterion             Criterion to match on
73         * @return                              True iff all entities satisfy the given criterion.
74         */
75        public boolean matchAll( List entityList ) {
76                for( entity in entityList ) {
77                        if( !matchOne( entity ) )
78                                return false;
79                }
80                return true;
81        }
82
83        /**
84         * Tries to match a value against a criterion and returns true if it matches
85         *
86         * @param value         Value of the field to match
87         * @return                      True iff the value matches this criterion, false otherwise
88         */
89        public boolean match( def fieldValue ) {
90                if( fieldValue == null )
91                        return false;
92                       
93                def classname = fieldValue.class.getName();
94                classname = classname[classname.lastIndexOf( '.' ) + 1..-1].toLowerCase();
95               
96                println "Match " + fieldValue + " of class " + classname + " with " + this
97               
98                try {
99                        switch( classname ) {
100                                case "integer":                                 return longCompare( new Long( fieldValue.longValue() ) );
101                                case "long":                                    return longCompare( fieldValue );
102                                case "float":                                   return doubleCompare( new Long( fieldValue.doubleValue() ) );
103                                case "double":                                  return doubleCompare( fieldValue );
104                                case "boolean":                                 return booleanCompare( fieldValue );
105                                case "date":                                    return dateCompare( fieldValue);
106                                case "reltime":                                 return relTimeCompare( fieldValue );
107                                case "assaymodule":
108                                case "template":
109                                case "term":
110                                case "templatefieldlistitem":
111                                case "string":
112                                default:                                                return compareValues( fieldValue.toString().trim().toLowerCase(), this.operator, value.toString().toLowerCase().trim() );
113                        }
114                } catch( Exception e ) {
115                        log.error e.class.getName() + ": " + e.getMessage();
116                        return false;
117                }
118        }
119
120        /**
121         * Tries to match a value against a criterion and returns true if it matches
122         *
123         * @param fieldValue            Value of the field to match
124         * @param operator                      Operator to apply
125         * @param criterionValue        Value of the criterion
126         * @return                                      True iff the value matches this criterion value, false otherwise
127         */
128        protected boolean compareValues( def fieldValue, Operator operator, def criterionValue ) {
129                switch( operator ) {
130                        case Operator.gte:
131                                return fieldValue >= criterionValue;
132                        case Operator.gt:
133                                return fieldValue > criterionValue;
134                        case Operator.lt:
135                                return fieldValue < criterionValue;
136                        case Operator.lte:
137                                return fieldValue <= criterionValue;
138                        case Operator.contains:
139                                return fieldValue.contains( criterionValue );
140                        case Operator.equals:
141                        default:
142                                return fieldValue.equals( criterionValue );
143                }
144
145        }
146
147        /**
148         * Tries to match a date value against a criterion and returns true if it matches
149         *
150         * @param value         Date value of the field to match
151         * @return                      True iff the value matches this criterion, false otherwise
152         */
153        protected boolean dateCompare( Date fieldValue ) {
154                try {
155                        Date dateCriterion = new SimpleDateFormat( "yyyy-MM-dd" ).parse( value );
156                        Date fieldDate = new Date( fieldValue.getTime() );
157                       
158                        // Clear time in order to just compare dates
159                        dateCriterion.clearTime();
160                        fieldDate.clearTime();
161                       
162                        return compareValues( fieldDate, this.operator, dateCriterion )
163                } catch( Exception e ) {
164                        log.error e.class.getName() + ": " + e.getMessage();
165                        return false;
166                }
167        }
168
169        /**
170         * Tries to match a long value against a criterion and returns true if it matches
171         *
172         * @param value         Long value of the field to match
173         * @param criterion     Criterion to match on. Should be a map with entries 'operator' and 'value'
174         * @return                      True iff the value matches this criterion, false otherwise
175         */
176        protected boolean longCompare( Long fieldValue ) {
177                Long longCriterion;
178                try {
179                        longCriterion = Long.parseLong( value );
180                } catch( Exception e ) {
181                        try {
182                                // If converting to long doesn't work, try converting to double and rounding it
183                                Double doubleCriterion = Double.parseDouble(value);
184                                longCriterion = new Long( doubleCriterion.longValue() );
185                        } catch( Exception e2 ) {
186                                log.error e2.class.getName() + ": " + e2.getMessage();
187                                return false;
188                        }
189                }
190                return compareValues( fieldValue, this.operator, longCriterion );
191        }
192
193        /**
194         * Tries to match a double value against a criterion and returns true if it matches
195         *
196         * @param value         Double value of the field to match
197         * @return                      True iff the value matches this criterion, false otherwise
198         */
199        protected boolean doubleCompare( Double fieldValue ) {
200                try {
201                        Double doubleCriterion = Double.parseDouble( value );
202                        return compareValues( fieldValue, this.operator, doubleCriterion );
203                } catch( Exception e ) {
204                        log.error e.class.getName() + ": " + e.getMessage();
205                        return false;
206                }
207        }
208
209
210        /**
211         * Tries to match a boolean value against a criterion and returns true if it matches
212         *
213         * @param value         Boolean value of the field to match
214         * @return                      True iff the value matches this criterion, false otherwise
215         */
216        protected boolean booleanCompare( Boolean fieldValue ) {
217                try {
218                        Boolean booleanCriterion = Boolean.parseBoolean( value );
219                        return compareValues( fieldValue, this.operator, booleanCriterion );
220                } catch( Exception e ) {
221                        log.error e.class.getName() + ": " + e.getMessage();
222                        return false;
223                }
224        }
225
226        /**
227         * Tries to match a relTime value against a criterion and returns true if it matches
228         *
229         * @param value         relTime value of the field to match
230         * @return                      True iff the value matches this criterion, false otherwise
231         */
232        protected boolean relTimeCompare( RelTime fieldValue ) {
233                try {
234                        RelTime rt
235
236                        // Numbers are taken to be seconds, if a non-numeric value is given, try to parse it
237                        if( value.toString().isNumber() ) {
238                                rt = new RelTime( Long.parseLong( value.toString() ) );
239                        } else {
240                                rt = new RelTime( value.toString() );
241                        }
242                       
243                        return compareValues( fieldValue, this.operator, rt );
244                } catch( Exception e ) {
245                        log.error e.class.getName() + ": " + e.getMessage();
246                        return false;
247                }
248        }
249
250        public String toString() {
251                return "[Criterion " + entity + "." + field + " " + operator + " " + value + "]";
252        }
253}
Note: See TracBrowser for help on using the repository browser.