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

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

Improved querying and created a possibility to search for assays

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