13
13
*/
14
14
package org .openmrs .api .db .hibernate ;
15
15
16
- import java .util .ArrayList ;
17
- import java .util .List ;
18
- import java .util .regex .Pattern ;
19
-
20
16
import org .hibernate .Criteria ;
21
17
import org .hibernate .Hibernate ;
22
18
import org .hibernate .SessionFactory ;
23
- import org .hibernate .criterion .Conjunction ;
24
- import org .hibernate .criterion .Criterion ;
25
19
import org .hibernate .criterion .Expression ;
26
20
import org .hibernate .criterion .LogicalExpression ;
27
21
import org .hibernate .criterion .MatchMode ;
34
28
import org .openmrs .util .OpenmrsConstants ;
35
29
import org .springframework .util .StringUtils ;
36
30
31
+ import java .util .ArrayList ;
32
+ import java .util .List ;
33
+ import java .util .regex .Pattern ;
34
+
37
35
/**
38
36
* The PatientSearchCriteria class. It has API to return a criteria from the Patient Name and
39
37
* identifier.
@@ -60,22 +58,10 @@ public PatientSearchCriteria(SessionFactory sessionFactory, Criteria criteria) {
60
58
* @param identifier
61
59
* @param identifierTypes
62
60
* @param matchIdentifierExactly
63
- * @param searchOnNamesOrIdentifiers specifies if the logic should find patients that match the
64
- * name or identifier otherwise find patients that match both the name and identifier
65
61
* @return {@link Criteria}
66
62
*/
67
63
public Criteria prepareCriteria (String name , String identifier , List <PatientIdentifierType > identifierTypes ,
68
- boolean matchIdentifierExactly , boolean orderByNames , boolean searchOnNamesOrIdentifiers ) {
69
-
70
- //Find patients that match either the name or identifier if only
71
- //the name or identifier was passed in to this method
72
- if (searchOnNamesOrIdentifiers && (name == null || identifier == null )) {
73
- if (name == null )
74
- name = identifier ;
75
- else
76
- identifier = name ;
77
- }
78
-
64
+ boolean matchIdentifierExactly , boolean orderByNames ) {
79
65
name = HibernateUtil .escapeSqlWildcards (name , sessionFactory );
80
66
identifier = HibernateUtil .escapeSqlWildcards (identifier , sessionFactory );
81
67
@@ -88,33 +74,20 @@ public Criteria prepareCriteria(String name, String identifier, List<PatientIden
88
74
89
75
// get only distinct patients
90
76
criteria .setResultTransformer (Criteria .DISTINCT_ROOT_ENTITY );
91
- Criterion nameCriterion = null ;
77
+
92
78
if (name != null ) {
93
- nameCriterion = prepareNameCriterion ( name );
79
+ addNameCriterias ( criteria , name );
94
80
}
95
81
96
- Criterion identifierCriterion = null ;
97
82
// do the restriction on either identifier string or types
98
83
if (identifier != null || identifierTypes .size () > 0 ) {
99
- identifierCriterion = prepareIdentifierCriterion (identifier , identifierTypes , matchIdentifierExactly ,
100
- searchOnNamesOrIdentifiers );
101
- }
102
-
103
- if (searchOnNamesOrIdentifiers ) {
104
- criteria .add (Restrictions .or (nameCriterion , identifierCriterion ));
105
- } else {
106
- if (nameCriterion != null ) {
107
- criteria .add (nameCriterion );
108
- }
109
- if (identifierCriterion != null ) {
110
- criteria .add (identifierCriterion );
111
- }
84
+ addIdentifierCriterias (criteria , identifier , identifierTypes , matchIdentifierExactly );
112
85
}
113
86
114
87
// TODO add junit test for searching on voided patients
115
88
116
89
// make sure the patient object isn't voided
117
- criteria .add (Restrictions .eq ("voided" , false ));
90
+ criteria .add (Expression .eq ("voided" , false ));
118
91
119
92
return criteria ;
120
93
}
@@ -127,21 +100,19 @@ public Criteria prepareCriteria(String name, String identifier, List<PatientIden
127
100
* @param identifierTypes
128
101
* @param matchIdentifierExactly
129
102
*/
130
- private Criterion prepareIdentifierCriterion (String identifier , List <PatientIdentifierType > identifierTypes ,
131
- boolean matchIdentifierExactly , boolean searchOnNamesOrIdentifiers ) {
132
-
133
- Conjunction conjuction = Restrictions .conjunction ();
103
+ private void addIdentifierCriterias (Criteria criteria , String identifier , List <PatientIdentifierType > identifierTypes ,
104
+ boolean matchIdentifierExactly ) {
134
105
// TODO add junit test for searching on voided identifiers
135
106
136
107
// add the join on the identifiers table
137
108
criteria .createAlias ("identifiers" , "ids" );
109
+ criteria .add (Expression .eq ("ids.voided" , false ));
138
110
139
- conjuction .add (Restrictions .eq ("ids.voided" , false ));
140
111
// do the identifier restriction
141
112
if (identifier != null ) {
142
113
// if the user wants an exact search, match on that.
143
114
if (matchIdentifierExactly ) {
144
- conjuction .add (Restrictions .eq ("ids.identifier" , identifier ). ignoreCase ( ));
115
+ criteria .add (Expression .eq ("ids.identifier" , identifier ));
145
116
} else {
146
117
AdministrationService adminService = Context .getAdministrationService ();
147
118
String regex = adminService .getGlobalProperty (OpenmrsConstants .GLOBAL_PROPERTY_PATIENT_IDENTIFIER_REGEX , "" );
@@ -154,18 +125,18 @@ private Criterion prepareIdentifierCriterion(String identifier, List<PatientIden
154
125
}
155
126
156
127
if (StringUtils .hasLength (patternSearch )) {
157
- conjuction . add ( splitAndGetSearchPattern ( identifier , patternSearch ) );
128
+ splitAndAddSearchPattern ( criteria , identifier , patternSearch );
158
129
}
159
130
// if the regex is empty, default to a simple "like" search or if
160
131
// we're in hsql world, also only do the simple like search (because
161
132
// hsql doesn't know how to deal with 'regexp'
162
133
else if (regex .equals ("" ) || HibernateUtil .isHSQLDialect (sessionFactory )) {
163
- conjuction . add ( getCriterionForSimpleSearch ( identifier , adminService ) );
134
+ addCriterionForSimpleSearch ( criteria , identifier , adminService );
164
135
}
165
136
// if the regex is present, search on that
166
137
else {
167
138
regex = replaceSearchString (regex , identifier );
168
- conjuction .add (Restrictions .sqlRestriction ("identifier regexp ?" , regex , Hibernate .STRING ));
139
+ criteria .add (Restrictions .sqlRestriction ("identifier regexp ?" , regex , Hibernate .STRING ));
169
140
}
170
141
}
171
142
}
@@ -174,38 +145,39 @@ else if (regex.equals("") || HibernateUtil.isHSQLDialect(sessionFactory)) {
174
145
175
146
// do the type restriction
176
147
if (identifierTypes .size () > 0 ) {
177
- criteria .add (Restrictions .in ("ids.identifierType" , identifierTypes ));
148
+ criteria .add (Expression .in ("ids.identifierType" , identifierTypes ));
178
149
}
179
150
180
- return conjuction ;
181
151
}
182
152
183
153
/**
184
154
* Utility method to add prefix and suffix like expression
185
155
*
156
+ * @param criteria
186
157
* @param identifier
187
158
* @param adminService
188
159
*/
189
- private Criterion getCriterionForSimpleSearch ( String identifier , AdministrationService adminService ) {
160
+ private void addCriterionForSimpleSearch ( Criteria criteria , String identifier , AdministrationService adminService ) {
190
161
String prefix = adminService .getGlobalProperty (OpenmrsConstants .GLOBAL_PROPERTY_PATIENT_IDENTIFIER_PREFIX , "" );
191
162
String suffix = adminService .getGlobalProperty (OpenmrsConstants .GLOBAL_PROPERTY_PATIENT_IDENTIFIER_SUFFIX , "" );
192
163
StringBuffer likeString = new StringBuffer (prefix ).append (identifier ).append (suffix );
193
- return Restrictions . ilike ( "ids.identifier" , likeString .toString ());
164
+ criteria . add ( Expression . like ( "ids.identifier" , likeString .toString () ));
194
165
}
195
166
196
167
/**
197
168
* Utility method to add search pattern expression to identifier.
198
169
*
170
+ * @param criteria
199
171
* @param identifier
200
172
* @param patternSearch
201
173
*/
202
- private Criterion splitAndGetSearchPattern ( String identifier , String patternSearch ) {
174
+ private void splitAndAddSearchPattern ( Criteria criteria , String identifier , String patternSearch ) {
203
175
// split the pattern before replacing in case the user searched on a comma
204
176
List <String > searchPatterns = new ArrayList <String >();
205
177
// replace the @SEARCH@, etc in all elements
206
178
for (String pattern : patternSearch .split ("," ))
207
179
searchPatterns .add (replaceSearchString (pattern , identifier ));
208
- return Restrictions . in ("ids.identifier" , searchPatterns );
180
+ criteria . add ( Expression . in ("ids.identifier" , searchPatterns ) );
209
181
}
210
182
211
183
/**
@@ -228,10 +200,7 @@ private String removePadding(String identifier, String regex) {
228
200
* @param criteria
229
201
* @param name
230
202
*/
231
- private Criterion prepareNameCriterion (String name ) {
232
-
233
- Conjunction conjuction = Restrictions .conjunction ();
234
-
203
+ private void addNameCriterias (Criteria criteria , String name ) {
235
204
// TODO simple name search to start testing, will need to make "real"
236
205
// name search
237
206
// i.e. split on whitespace, guess at first/last name, etc
@@ -254,14 +223,12 @@ private Criterion prepareNameCriterion(String name) {
254
223
if (i > 0 ) {
255
224
nameSoFar += " " + n ;
256
225
LogicalExpression fullNameSearch = getNameSearch (nameSoFar );
257
- searchExpression = Restrictions .or (oneNameSearch , fullNameSearch );
226
+ searchExpression = Expression .or (oneNameSearch , fullNameSearch );
258
227
}
259
- conjuction .add (searchExpression );
228
+ criteria .add (searchExpression );
260
229
}
261
230
}
262
231
}
263
-
264
- return conjuction ;
265
232
}
266
233
267
234
/**
@@ -273,7 +240,6 @@ private Criterion prepareNameCriterion(String name) {
273
240
* <pre>
274
241
* ... where voided = false && name in (familyName2, familyName, middleName, givenName)
275
242
* </pre>
276
- *
277
243
* Except when the name provided is less than min characters (usually 3) then we will look for
278
244
* an EXACT match by default
279
245
*
0 commit comments