1 package org.apache.ojb.broker.query;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.apache.ojb.broker.metadata.ClassDescriptor;
26 import org.apache.ojb.broker.metadata.FieldDescriptor;
27 import org.apache.ojb.broker.metadata.FieldHelper;
28 import org.apache.ojb.broker.metadata.MetadataManager;
29 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
30 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
31 import org.apache.ojb.broker.util.logging.LoggerFactory;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class QueryByCriteria extends AbstractQueryImpl
52 {
53 private Criteria m_criteria;
54 private boolean m_distinct = false;
55 private Map m_pathClasses;
56 private Criteria m_havingCriteria;
57 private String m_objectProjectionAttribute;
58
59
60 private List m_orderby = null;
61 private List m_groupby = null;
62
63
64 private List m_prefetchedRelationships = null;
65
66 private Collection m_pathOuterJoins = null;
67
68
69
70
71
72 public static final Criteria CRITERIA_SELECT_ALL = null;
73
74
75
76
77
78 public QueryByCriteria(Class targetClass, Criteria whereCriteria, Criteria havingCriteria, boolean distinct)
79 {
80 super (targetClass);
81
82 setCriteria(whereCriteria);
83 setHavingCriteria(havingCriteria);
84
85 m_distinct = distinct;
86 m_pathClasses = new HashMap();
87 m_groupby = new ArrayList();
88 m_orderby = new ArrayList();
89 m_prefetchedRelationships = new ArrayList();
90 m_pathOuterJoins = new HashSet();
91 }
92
93
94
95
96
97 public QueryByCriteria(Class targetClass, Criteria whereCriteria, Criteria havingCriteria)
98 {
99 this(targetClass, whereCriteria, havingCriteria, false);
100 }
101
102
103
104
105
106
107 public QueryByCriteria(Class targetClass, Criteria criteria)
108 {
109 this(targetClass, criteria, false);
110 }
111
112
113
114
115
116 public QueryByCriteria(Class targetClass, Criteria criteria, boolean distinct)
117 {
118 this(targetClass, criteria, null, distinct);
119 }
120
121
122
123
124
125 public QueryByCriteria(Object anObject, boolean distinct)
126 {
127 this(anObject.getClass(), buildCriteria(anObject), distinct);
128 }
129
130
131
132
133
134 public QueryByCriteria(Object anObject)
135 {
136 this(anObject.getClass(), buildCriteria(anObject));
137 }
138
139
140
141
142
143
144 public QueryByCriteria(Class aClassToSearchFrom)
145 {
146 this(aClassToSearchFrom, CRITERIA_SELECT_ALL);
147 }
148
149
150
151
152
153 private static Criteria buildCriteria(Object anExample)
154 {
155 Criteria criteria = new Criteria();
156 ClassDescriptor cld = MetadataManager.getInstance().getRepository().getDescriptorFor(anExample.getClass());
157 FieldDescriptor[] fds = cld.getFieldDescriptions();
158 PersistentField f;
159 Object value;
160
161 for (int i = 0; i < fds.length; i++)
162 {
163 try
164 {
165 f = fds[i].getPersistentField();
166 value = f.get(anExample);
167 if (value != null)
168 {
169 criteria.addEqualTo(f.getName(), value);
170 }
171 }
172 catch (Throwable ex)
173 {
174 LoggerFactory.getDefaultLogger().error(ex);
175 }
176 }
177
178 return criteria;
179 }
180
181
182
183
184
185
186
187
188
189
190
191 public void addPathClass(String aPath, Class aClass)
192 {
193 List pathClasses = (List) m_pathClasses.get(aPath);
194 if(pathClasses == null)
195 {
196 setPathClass(aPath, aClass);
197 }
198 else
199 {
200 pathClasses.add(aClass);
201 }
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215
216 public void setPathClass(String aPath, Class aClass)
217 {
218 List pathClasses = new ArrayList();
219 pathClasses.add(aClass);
220 m_pathClasses.put(aPath, pathClasses);
221 }
222
223
224
225
226
227
228
229
230
231 public List getClassesForPath(String aPath)
232 {
233 return (List)m_pathClasses.get(aPath);
234 }
235
236
237
238
239
240
241 public boolean isPathOuterJoin(String aPath)
242 {
243 return getOuterJoinPaths().contains(aPath);
244 }
245
246
247
248
249
250
251
252 public void setPathOuterJoin(String aPath)
253 {
254 getOuterJoinPaths().add(aPath);
255 }
256
257
258
259
260 public Criteria getCriteria()
261 {
262 return m_criteria;
263 }
264
265
266
267
268 public Criteria getHavingCriteria()
269 {
270 return m_havingCriteria;
271 }
272
273
274
275
276
277
278 public String toString()
279 {
280 StringBuffer buf = new StringBuffer("QueryByCriteria from ");
281 buf.append(getSearchClass()).append(" ");
282 if (getCriteria() != null && !getCriteria().isEmpty())
283 {
284 buf.append(" where ").append(getCriteria());
285 }
286 return buf.toString();
287 }
288
289
290
291
292
293 public boolean isDistinct()
294 {
295 return m_distinct;
296 }
297
298
299
300
301
302 public void setDistinct(boolean distinct)
303 {
304 this.m_distinct = distinct;
305 }
306
307
308
309
310
311
312 public Map getPathClasses()
313 {
314 return m_pathClasses;
315 }
316
317
318
319
320
321 public void setCriteria(Criteria criteria)
322 {
323 m_criteria = criteria;
324 if (m_criteria != null)
325 {
326 m_criteria.setQuery(this);
327 }
328 }
329
330
331
332
333
334 public void setHavingCriteria(Criteria havingCriteria)
335 {
336 m_havingCriteria = havingCriteria;
337 if (m_havingCriteria != null)
338 {
339 m_havingCriteria.setQuery(this);
340 }
341 }
342
343
344
345
346
347 public void addGroupBy(String fieldName)
348 {
349 if (fieldName != null)
350 {
351 m_groupby.add(new FieldHelper(fieldName, false));
352 }
353 }
354
355
356
357
358
359 public void addGroupBy(FieldHelper aField)
360 {
361 if (aField != null)
362 {
363 m_groupby.add(aField);
364 }
365 }
366
367
368
369
370
371 public void addGroupBy(String[] fieldNames)
372 {
373 for (int i = 0; i < fieldNames.length; i++)
374 {
375 addGroupBy(fieldNames[i]);
376 }
377 }
378
379
380
381
382 public List getGroupBy()
383 {
384
385
386
387 ArrayList temp = new ArrayList();
388 temp.addAll(m_groupby);
389
390 if (getCriteria() != null)
391 {
392 temp.addAll(getCriteria().getGroupby());
393 }
394
395 return temp;
396 }
397
398
399
400
401
402
403 public void addOrderBy(String fieldName, boolean sortAscending)
404 {
405 if (fieldName != null)
406 {
407 m_orderby.add(new FieldHelper(fieldName, sortAscending));
408 }
409 }
410
411
412
413
414
415
416 public void addOrderBy(String fieldName)
417 {
418 addOrderBy(fieldName, true);
419 }
420
421
422
423
424
425 public void addOrderBy(FieldHelper aField)
426 {
427 if (aField != null)
428 {
429 m_orderby.add(aField);
430 }
431 }
432
433
434
435
436
437 public void addOrderByAscending(String fieldName)
438 {
439 addOrderBy(fieldName, true);
440 }
441
442
443
444
445
446 public void addOrderByDescending(String fieldName)
447 {
448 addOrderBy(fieldName, false);
449 }
450
451
452
453
454 public List getOrderBy()
455 {
456
457
458
459 ArrayList temp = new ArrayList();
460 temp.addAll(m_orderby);
461
462 if (getCriteria() != null)
463 {
464 temp.addAll(getCriteria().getOrderby());
465 }
466
467 return temp;
468 }
469
470
471
472
473 public void addPrefetchedRelationship(String aName)
474 {
475 m_prefetchedRelationships.add(aName);
476 }
477
478
479
480
481 public List getPrefetchedRelationships()
482 {
483
484
485
486 ArrayList temp = new ArrayList();
487 temp.addAll(m_prefetchedRelationships);
488
489 if (getCriteria() != null)
490 {
491 temp.addAll(getCriteria().getPrefetchedRelationships());
492 }
493
494 return temp;
495 }
496
497
498
499
500
501 public Collection getOuterJoinPaths()
502 {
503 return m_pathOuterJoins;
504 }
505
506 public String getObjectProjectionAttribute()
507 {
508 return m_objectProjectionAttribute;
509 }
510
511
512
513
514
515 public void setObjectProjectionAttribute(String objectProjectionAttribute)
516 {
517 ClassDescriptor baseCld = MetadataManager.getInstance().getRepository().getDescriptorFor(m_baseClass);
518 ArrayList descs = baseCld.getAttributeDescriptorsForPath(objectProjectionAttribute);
519 int pathLen = descs.size();
520
521 if ((pathLen > 0) && (descs.get(pathLen - 1) instanceof ObjectReferenceDescriptor))
522 {
523 ObjectReferenceDescriptor ord =
524 ((ObjectReferenceDescriptor) descs.get(pathLen - 1));
525 setObjectProjectionAttribute(objectProjectionAttribute,
526 ord.getItemClass());
527 }
528 }
529
530 public void setObjectProjectionAttribute(String objectProjectionAttribute,
531 Class objectProjectionClass)
532 {
533 m_objectProjectionAttribute = objectProjectionAttribute;
534 m_searchClass = objectProjectionClass;
535 }
536 }