1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.smartlab.web;
24
25 import java.io.Serializable;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.Locale;
29 import java.util.StringTokenizer;
30
31 import net.smartlab.web.bean.ConversionException;
32 import net.smartlab.web.bean.ConverterManager;
33
34 import org.apache.commons.lang.builder.EqualsBuilder;
35 import org.apache.commons.lang.builder.HashCodeBuilder;
36 import org.apache.commons.lang.builder.ToStringBuilder;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40
41
42
43
44
45
46
47 public interface DataAccessObject {
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 public Object findByKey(Serializable key) throws DAOException;
63
64
65
66
67
68
69
70
71
72 public void remove(Object object) throws DAOException;
73
74
75
76
77
78
79
80
81
82
83
84 public void update(Object object) throws DAOException;
85
86
87
88
89
90
91
92
93
94
95 public Collection list(SearchInfo info) throws DAOException;
96
97
98
99
100
101
102
103
104
105
106
107 public static class SearchInfo implements Serializable {
108
109 private static final long serialVersionUID = 1038393869915276007L;
110
111 private static final Log logger = LogFactory.getLog(SearchInfo.class);
112
113
114
115
116
117
118 private Collection filters = new ArrayList();
119
120
121
122
123
124
125 private String order = null;
126
127
128
129
130
131
132 private boolean descendant = false;
133
134
135
136
137
138
139 private boolean union = false;
140
141
142
143
144 private Locale locale = Locale.getDefault();
145
146
147
148
149 public final static int EQUALS = 1;
150
151
152
153
154 public final static int GREATER = 2;
155
156
157
158
159 public final static int GREATER_EQUALS = 3;
160
161
162
163
164 public final static int LESSER = 4;
165
166
167
168
169 public final static int LESSER_EQUALS = 5;
170
171
172
173
174 public final static int NOT_EQUALS = -1;
175
176
177
178
179 public final static int LIKE = 6;
180
181
182
183
184 public final static int ILIKE = 7;
185
186
187
188
189 public final static int BETWEEN = 8;
190
191
192
193
194 public final static int NULL = 9;
195
196
197
198
199 public final static int NOT_NULL = -9;
200
201
202
203
204 public final static int IN = 11;
205
206
207
208
209 public final static int NOT_IN = -11;
210
211
212
213
214
215
216 public boolean isDescendant() {
217 return descendant;
218 }
219
220
221
222
223
224 public Collection getFilters() {
225 return filters;
226 }
227
228
229
230
231
232 public void setFilters(Collection filters) {
233 this.filters = filters;
234 }
235
236
237
238
239 public void setFilters(String[] filters) {
240 if (filters != null) {
241 for (int i = 0; i < filters.length; i++) {
242 this.addFilter(filters[i]);
243 }
244 }
245 }
246
247
248
249
250
251
252 public void addFilter(String filter) {
253 try {
254 for (int i = 0; i < filter.length(); i++) {
255 switch (filter.charAt(i)) {
256
257 case '!':
258 if (filter.charAt(i + 1) == '|') {
259 filters.add(new Filter(filter.substring(0, i), NOT_IN, filter.substring(i + 2)));
260 } else {
261 filters.add(new Filter(filter.substring(0, i), NOT_EQUALS, filter.substring(i + 1)));
262 }
263 return;
264
265 case '=':
266 filters.add(new Filter(filter.substring(0, i), EQUALS, filter.substring(i + 1)));
267 return;
268
269 case '>':
270
271 if (filter.charAt(i + 1) == '=') {
272 filters
273 .add(new Filter(filter.substring(0, i), GREATER_EQUALS, filter.substring(i + 2)));
274 } else {
275 filters.add(new Filter(filter.substring(0, i), GREATER, filter.substring(i + 1)));
276 }
277 return;
278
279 case '<':
280
281 if (filter.charAt(i + 1) == '=') {
282 filters.add(new Filter(filter.substring(0, i), LESSER_EQUALS, filter.substring(i + 2)));
283 } else {
284 filters.add(new Filter(filter.substring(0, i), LESSER, filter.substring(i + 1)));
285 }
286 return;
287
288 case '|':
289 if (filter.charAt(i + 1) == '|') {
290 filters.add(new Filter(filter.substring(0, i), IN, filter.substring(i + 2)));
291 } else {
292 filters.add(new Filter(filter.substring(0, i), BETWEEN, filter.substring(i + 1)));
293 }
294 return;
295
296 case '%':
297 if (filter.charAt(i + 1) == '%') {
298
299 filters.add(new Filter(filter.substring(0, i), ILIKE, filter.substring(i + 2)));
300 return;
301 } else {
302
303 filters.add(new Filter(filter.substring(0, i), LIKE, filter.substring(i + 1)));
304 return;
305 }
306 case '\\':
307 i++;
308 continue;
309 }
310 }
311 } catch (SkipFilterException sfe) {
312 logger.debug("skipping filter `" + filter + "`");
313 }
314 }
315
316
317
318
319
320
321
322
323
324 public void addFilter(String property, int condition, String values) {
325 try {
326 filters.add(new Filter(property, condition, values));
327 } catch (SkipFilterException sfe) {
328 logger.debug("skipping filter on `" + property + "` with condition " + condition + " and values `"
329 + values + "`");
330 }
331 }
332
333
334
335
336
337
338
339
340
341 public void addFilter(String property, int condition, Object value) throws ConversionException {
342 try {
343 filters.add(new Filter(property, condition, (String)ConverterManager.getDefault().convert(String.class, value, locale)));
344 } catch (SkipFilterException sfe) {
345 logger.debug("skipping filter on `" + property + "` with condition " + condition + " and value `"
346 + value + "`");
347 }
348 }
349
350
351
352
353
354
355
356
357 public void addFilter(String property, int condition, String[] values) {
358 try {
359 StringBuffer buffer = new StringBuffer();
360 for (int i = 0; i < values.length; i++) {
361 buffer.append(values[i]);
362 buffer.append(',');
363 }
364 filters.add(new Filter(property, condition, buffer.toString()));
365 } catch (SkipFilterException sfe) {
366 logger.debug("skipping filter on `" + property + "` with condition " + condition + " and values `"
367 + values + "`");
368 }
369 }
370
371
372
373
374
375
376
377
378
379 public void addFilter(String property, int condition, Object[] values) throws ConversionException {
380 try {
381 StringBuffer buffer = new StringBuffer();
382 for (int i = 0; i < values.length; i++) {
383 buffer.append(ConverterManager.getDefault().convert(String.class, values[i], locale));
384 buffer.append(',');
385 }
386 filters.add(new Filter(property, condition, buffer.toString()));
387 } catch (SkipFilterException sfe) {
388 logger.debug("skipping filter on `" + property + "` with condition " + condition + " and values `"
389 + values + "`");
390 }
391 }
392
393
394
395
396
397 public String getOrder() {
398 return order;
399 }
400
401
402
403
404
405
406
407
408
409
410
411
412 public void setOrder(String order) {
413 if (order != null && order.length() > 0) {
414 if (order.charAt(0) == '!') {
415 this.order = order.substring(1);
416 this.descendant = true;
417 } else {
418 this.order = order;
419 this.descendant = false;
420 }
421 } else {
422 this.order = null;
423 }
424 }
425
426
427
428
429
430
431 public void setUnion(String style) {
432 if (style != null && style.length() > 0) {
433 if (style.equalsIgnoreCase("OR") || style.equalsIgnoreCase("true") || style.equalsIgnoreCase("yes") || style.equalsIgnoreCase("y")) {
434 this.union = true;
435 } else {
436 this.union = false;
437 }
438 }
439 }
440
441
442
443
444
445
446
447
448 public void setUnion(boolean union) {
449 this.union = union;
450 }
451
452
453
454
455
456
457
458 public boolean isUnion() {
459 return union;
460 }
461
462
463
464
465
466
467 public void setLocale(Locale locale) {
468 this.locale = locale;
469 }
470
471
472
473
474
475
476 public Locale getLocale() {
477 return locale;
478 }
479
480
481
482
483 public String toString() {
484 return new ToStringBuilder(this).append(this.filters).append(this.order).append(this.descendant).append(
485 this.union).append(this.locale).toString();
486 }
487
488
489
490
491
492
493
494
495 protected class Filter {
496
497
498
499
500
501
502 private String property;
503
504
505
506
507
508
509 private int condition;
510
511
512
513
514
515
516 private String[] values;
517
518
519
520
521
522
523
524
525
526
527
528 private Filter(String property, int condition, String values) throws SkipFilterException {
529 if (values == null) {
530 throw new SkipFilterException();
531 }
532 this.property = property;
533 this.condition = condition;
534 StringTokenizer tokenizer = new StringTokenizer(values, ",", false);
535 this.values = new String[tokenizer.countTokens()];
536 for (int i = 0; tokenizer.hasMoreTokens(); i++) {
537 this.values[i] = tokenizer.nextToken();
538 if (this.values[i].indexOf('\\') > -1) {
539 StringBuffer buffer = new StringBuffer();
540 for (int j = 0; j < this.values[i].length(); j++) {
541 char c = this.values[i].charAt(j);
542 switch (c) {
543 case '\\':
544 if (this.values[i].length() > j + 1 && this.values[i].charAt(j + 1) == '\\') {
545 buffer.append(c);
546 j++;
547 }
548 break;
549 default:
550 buffer.append(c);
551 }
552 }
553 this.values[i] = buffer.toString();
554 }
555 }
556 if (this.values.length == 1 && this.values[0].equals("NULL")
557 && (condition == EQUALS || condition == NOT_EQUALS)) {
558 if (condition == EQUALS) {
559 this.condition = NULL;
560 } else if (condition == NOT_EQUALS) {
561 this.condition = NOT_NULL;
562 }
563 this.values = null;
564 } else if (this.values.length == 0) {
565 throw new SkipFilterException();
566 }
567 logger.trace("adding filter on `" + property + "` with condition " + condition + " and values `" + values
568 + "`");
569 }
570
571
572
573
574
575 protected String getColumn() {
576 return property;
577 }
578
579
580
581
582
583
584
585
586 protected String getProperty() {
587 return property;
588 }
589
590
591
592
593
594
595
596 protected int getCondition() {
597 return condition;
598 }
599
600
601
602
603
604
605
606 protected String[] getValues() {
607 return values;
608 }
609
610
611
612
613
614
615
616
617 protected String getValue(int index) {
618 return values[index];
619 }
620
621
622
623
624 public boolean equals(Object object) {
625 if (!(object instanceof Filter)) {
626 return false;
627 }
628 Filter filter = (Filter)object;
629 return new EqualsBuilder().append(this.property, filter.property).append(this.condition, filter.condition)
630 .append(this.values, filter.values).isEquals();
631 }
632
633
634
635
636 public int hashCode() {
637 return new HashCodeBuilder(-27848275, 353473951).append(this.property).append(this.condition).append(
638 this.values).toHashCode();
639 }
640
641
642
643
644 public String toString() {
645 return new ToStringBuilder(this).append(this.property).append(this.condition).append(this.values)
646 .toString();
647 }
648 }
649
650 private static class SkipFilterException extends Exception {
651
652 private static final long serialVersionUID = 5576925342229697415L;
653 }
654 }
655 }