KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > SessionResultFilter


1 /**
2  * $RCSfile: SessionResultFilter.java,v $
3  * $Revision: 1.5 $
4  * $Date: 2004/12/01 21:46:33 $
5  *
6  * Copyright (C) 2004 Jive Software. All rights reserved.
7  *
8  * This software is published under the terms of the GNU Public License (GPL),
9  * a copy of which is included in this distribution.
10  */

11
12 package org.jivesoftware.messenger;
13
14 import java.util.Comparator JavaDoc;
15 import java.util.Date JavaDoc;
16
17 /**
18  * <p>Filters and sorts lists of sessions.</p>
19  * <p>This allows for a very
20  * rich set of possible queries that can be run on session data. Some examples
21  * are: "Show all sessions started during the last hour by a
22  * certain user".
23  * </p><p>
24  * The class also supports pagination of results with the setStartIndex(int)
25  * and setNumResults(int) methods. If the start index is not set, it will
26  * begin at index 0 (the start of results). If the number of results is not set,
27  * it will be unbounded and return as many results as available.
28  * </p><p>
29  * Factory methods to create common queries are provided for convenience.
30  * </p>
31  *
32  * @author Iain Shigeoka
33  */

34 public class SessionResultFilter {
35
36     // ############################################################
37
// Search order criteria
38
// ############################################################
39
/**
40      * Descending sort (ie 3, 2, 1...).
41      */

42     public static final int DESCENDING = 0;
43
44     /**
45      * Ascending sort (ie 3, 4, 5...).
46      */

47     public static final int ASCENDING = 1;
48
49     // ############################################################
50
// Result limit search criteria
51
// ############################################################
52
/**
53      * <p>Represents no result limit (infinite results).</p>
54      */

55     public static final int NO_RESULT_LIMIT = -1;
56
57     // ############################################################
58
// Packet limit search criteria
59
// ############################################################
60
/**
61      * <p>Represents no result limit (infinite results).</p>
62      */

63     public static final long NO_PACKET_LIMIT = -1;
64     // ############################################################
65
// Sort fields
66
// ############################################################
67
public static final int SORT_USER = 0;
68     public static final int SORT_CREATION_DATE = 1;
69     public static final int SORT_LAST_ACTIVITY_DATE = 2;
70     public static final int SORT_NUM_CLIENT_PACKETS = 3;
71     public static final int SORT_NUM_SERVER_PACKETS = 4;
72
73     /**
74      * <p>Creates a default SessionResultFilter: no filtering with results sorted
75      * by user.</p>
76      */

77     public static SessionResultFilter createDefaultSessionFilter() {
78         SessionResultFilter resultFilter = new SessionResultFilter();
79         resultFilter.setSortField(SORT_USER);
80         resultFilter.setSortOrder(ASCENDING);
81         return resultFilter;
82     }
83
84     private int sortField = SORT_LAST_ACTIVITY_DATE;
85     private int sortOrder = DESCENDING;
86     private long clientPacketRangeMin = NO_PACKET_LIMIT;
87     private long clientPacketRangeMax = NO_PACKET_LIMIT;
88     private long serverPacketRangeMin = NO_PACKET_LIMIT;
89     private long serverPacketRangeMax = NO_PACKET_LIMIT;
90
91     private String JavaDoc username = null;
92
93     /**
94      * The starting index for results. Default is 0.
95      */

96     private int startIndex = 0;
97
98     /**
99      * Number of results to return. Default is NO_RESULT_LIMIT
100      * which means an unlimited number of results.
101      */

102     private int numResults = NO_RESULT_LIMIT;
103
104     private Date JavaDoc creationDateRangeMin = null;
105     private Date JavaDoc creationDateRangeMax = null;
106     private Date JavaDoc lastActivityDateRangeMin = null;
107     private Date JavaDoc lastActivityDateRangeMax = null;
108
109     /**
110      * Returns the username that results will be filtered on. The method will
111      * return <tt>null</tt> if no user to filter on has been specified.
112      *
113      * @return the username that results will be filtered on.
114      */

115     public String JavaDoc getUsername() {
116         return username;
117     }
118
119     /**
120      * Sets the username that results will be filtered on. By default, no filtering on
121      * username will take place. To avoid filtering on username pass in <tt>null</tt>.
122      *
123      * @param username the user ID to filter on.
124      */

125     public void setUsername(String JavaDoc username) {
126         this.username = username;
127     }
128
129     /**
130      * Returns the creation date that represents the lower boundary for
131      * sessions to be filtered on. If this value has not been set, the method
132      * will return null.
133      *
134      * @return a Date representing the lower bound for creation dates to filter on.
135      */

136     public Date JavaDoc getCreationDateRangeMin() {
137         return creationDateRangeMin;
138     }
139
140     /**
141      * Sets the date that represents the lower boundary for sessions to
142      * be selected by the result filter. If this value is not set the results filter will
143      * be unbounded for the earliest creation date selected.<p>
144      *
145      * @param creationDateRangeMin Date representing the filter lowest value of
146      * the creation date to be selected.
147      */

148     public void setCreationDateRangeMin(Date JavaDoc creationDateRangeMin) {
149         this.creationDateRangeMin = creationDateRangeMin;
150     }
151
152     /**
153      * Returns a date that represents the upper boundry for sessions to
154      * be selected by the result filter. If this value is not set it will return null
155      * and the results filter will be unbounded for the latest creation date selected.
156      *
157      * @return a Date representing the filter highest value of the creation date to be
158      * selected.
159      */

160     public Date JavaDoc getCreationDateRangeMax() {
161         return creationDateRangeMax;
162     }
163
164     /**
165      * Sets a date that represents the upper boundry for sessions to
166      * be selected by the result filter. If this value is not set the results
167      * filter will be unbounded for the latest creation date selected.
168      *
169      * @param creationDateRangeMax Date representing the filter lowest value of
170      * the creation date range.
171      */

172     public void setCreationDateRangeMax(Date JavaDoc creationDateRangeMax) {
173         this.creationDateRangeMax = creationDateRangeMax;
174     }
175
176     /**
177      * Returns a date that represents the lower boundary for session
178      * to be selected by the result filter. If this value is not set it will
179      * return null and the results filter will be unbounded for the earliest
180      * last activity date selected.
181      *
182      * @return a Date representing the filter lowest value of the last activity date
183      * range.
184      */

185     public Date JavaDoc getLastActivityDateRangeMin() {
186         return lastActivityDateRangeMin;
187     }
188
189     /**
190      * Sets a date that represents the lower boundary for sessions to
191      * be selected by the result filter. If this value is not set the results
192      * filter will be unbounded for the earliest last activity date selected.
193      *
194      * @param lastActivityDateRangeMin Date representing the filter lowest value of
195      * the last activity date to be selected.
196      */

197     public void setLastActivityDateRangeMin(Date JavaDoc lastActivityDateRangeMin) {
198         this.lastActivityDateRangeMin = lastActivityDateRangeMin;
199     }
200
201     /**
202      * Returns a date that represents the upper boundry for sessions to
203      * be selected by the result filter. If this value is not set it will return null
204      * and the results filter will be unbounded for the latest activity date selected.
205      *
206      * @return a Date representing the filter highest value of the last activity date to be
207      * selected.
208      */

209     public Date JavaDoc getLastActivityDateRangeMax() {
210         return lastActivityDateRangeMax;
211     }
212
213     /**
214      * Sets a date that represents the upper boundry for sessions to
215      * be selected by the result filter. If this value is not set the results filter will
216      * be unbounded for the latest activity date selected.
217      *
218      * @param lastActivityDateRangeMax Date representing the filter lowest value of
219      * the last activity date range.
220      */

221     public void setLastActivityDateRangeMax(Date JavaDoc lastActivityDateRangeMax) {
222         this.lastActivityDateRangeMax = lastActivityDateRangeMax;
223     }
224
225     /**
226      * <p>Get a lower boundary on client packets for sessions to be
227      * selected by the result filter.</p>
228      * <p>A value of NO_PACKET_LIMIT will be returned if
229      * there is lower packet limit.</p>
230      *
231      * @return The upper limit of client packets allowed for sessions to meet this filter requirement
232      */

233     public long getClientPacketRangeMin() {
234         return clientPacketRangeMin;
235     }
236
237     /**
238      * <p>Set an lower boundary on client packets for sessions to be
239      * selected by the result filter.</p>
240      * <p>If this value is not set
241      * the results filter will have no lower bounds for client packets selected.</p>
242      *
243      * @param max The lower limit of client packets allowed for sessions to meet this filter requirement
244      */

245     public void setClientPacketRangeMin(long max) {
246         this.clientPacketRangeMin = max;
247     }
248
249     /**
250      * <p>Get an upper boundary on client packets for sessions to be
251      * selected by the result filter.</p>
252      * <p>A value of NO_PACKET_LIMIT will be returned if
253      * there is upper packet limit.</p>
254      *
255      * @return The upper limit of client packets allowed for sessions to meet this filter requirement
256      */

257     public long getClientPacketRangeMax() {
258         return clientPacketRangeMax;
259     }
260
261     /**
262      * <p>Set an upper boundary on client packets for sessions to be
263      * selected by the result filter.</p>
264      * <p>If this value is not set
265      * the results filter will have no upper bounds
266      * for client packets selected.</p>
267      *
268      * @param max The upper limit of client packets allowed for sessions to meet this filter requirement
269      */

270     public void setClientPacketRangeMax(long max) {
271         this.clientPacketRangeMax = max;
272     }
273
274     /**
275      * <p>Get a lower boundary on server packets for sessions to be
276      * selected by the result filter.</p>
277      * <p>A value of NO_PACKET_LIMIT will be returned if
278      * there is lower packet limit.</p>
279      *
280      * @return The upper limit of server packets allowed for sessions to meet this filter requirement
281      */

282     public long getServerPacketRangeMin() {
283         return serverPacketRangeMin;
284     }
285
286     /**
287      * <p>Set an lower boundary on server packets for sessions to be
288      * selected by the result filter.</p>
289      * <p>If this value is not set
290      * the results filter will have no lower bounds for server packets selected.</p>
291      *
292      * @param max The lower limit of server packets allowed for sessions to meet this filter requirement
293      */

294     public void setServerPacketRangeMin(long max) {
295         this.serverPacketRangeMin = max;
296     }
297
298     /**
299      * <p>Get an upper boundary on server packets for sessions to be
300      * selected by the result filter.</p>
301      * <p>A value of NO_PACKET_LIMIT will be returned if
302      * there is upper packet limit.</p>
303      *
304      * @return The upper limit of server packets allowed for sessions to meet this filter requirement
305      */

306     public long getServerPacketRangeMax() {
307         return serverPacketRangeMax;
308     }
309
310     /**
311      * <p>Set an upper boundary on server packets for sessions to be
312      * selected by the result filter.</p>
313      * <p>If this value is not set
314      * the results filter will have no upper bounds
315      * for server packets selected.</p>
316      *
317      * @param max The upper limit of server packets allowed for sessions to meet this filter requirement
318      */

319     public void setServerPacketRangeMax(long max) {
320         this.serverPacketRangeMax = max;
321     }
322
323     /**
324      * Returns the currently selected sort field. The default value is
325      * SessionResultFilter.SORT_LAST_ACTIVITY_DATE.
326      *
327      * @return current sort field.
328      */

329     public int getSortField() {
330         return sortField;
331     }
332
333     /**
334      * Sets the sort field to use. The default value is
335      * SessionResultFilter.SORT_LAST_ACTIVITY_DATE.
336      *
337      * @param sortField the field that will be used for sorting.
338      */

339     public void setSortField(int sortField) {
340         this.sortField = sortField;
341     }
342
343     /**
344      * Returns the sort order, which will be SessionResultFilter.ASCENDING for
345      * ascending sorting, or SessionResultFilter.DESCENDING for descending sorting.
346      * Descending sorting is: 3, 2, 1, etc. Ascending sorting is 1, 2, 3, etc.
347      *
348      * @return the sort order.
349      */

350     public int getSortOrder() {
351         return this.sortOrder;
352     }
353
354     /**
355      * Sets the sort type. Valid arguments are SessionResultFilter.ASCENDING for
356      * ascending sorting or SessionResultFilter.DESCENDING for descending sorting.
357      * Descending sorting is: 3, 2, 1, etc. Ascending sorting is 1, 2, 3, etc.
358      *
359      * @param sortOrder the order that results will be sorted in.
360      */

361     public void setSortOrder(int sortOrder) {
362         if (!(sortOrder == SessionResultFilter.ASCENDING || sortOrder == SessionResultFilter.DESCENDING)) {
363             throw new IllegalArgumentException JavaDoc();
364         }
365         this.sortOrder = sortOrder;
366     }
367
368     /**
369      * <p>Returns the max number of results that should be returned.</p>
370      * <p>The default value for is NO_RESULT_LIMIT, which means there will be no limit
371      * on the number of results. This method can be used in combination with
372      * setStartIndex(int) to perform pagination of results.</p>
373      *
374      * @return the max number of results to return or NO_RESULT_LIMIT for no limit
375      * @see #setStartIndex(int)
376      */

377     public int getNumResults() {
378         return numResults;
379     }
380
381     /**
382      * <p>Sets the limit on the number of results to be returned.</p>
383      * <p>User NO_RESULT_LIMIT if you don't want to limit the results returned.</p>
384      *
385      * @param numResults the number of results to return or NO_RESULT_LIMIT for no limit
386      */

387     public void setNumResults(int numResults) {
388         if (numResults != NO_RESULT_LIMIT && numResults < 0) {
389             throw new IllegalArgumentException JavaDoc("numResults cannot be less than 0.");
390         }
391         this.numResults = numResults;
392     }
393
394     /**
395      * Returns the index of the first result to return.
396      *
397      * @return the index of the first result which should be returned.
398      */

399     public int getStartIndex() {
400         return startIndex;
401     }
402
403     /**
404      * Sets the index of the first result to return. For example, if the start
405      * index is set to 20, the Iterator returned will start at the 20th result
406      * in the query. This method can be used in combination with
407      * setNumResults(int) to perform pagination of results.
408      *
409      * @param startIndex the index of the first result to return.
410      */

411     public void setStartIndex(int startIndex) {
412         if (startIndex < 0) {
413             throw new IllegalArgumentException JavaDoc("A start index less than 0 is not valid.");
414         }
415         this.startIndex = startIndex;
416     }
417
418     /**
419      * <p>Obtains a comparator that will sort a standard sorted set according
420      * to this filter's sort order.</p>
421      *
422      * @return A comparator that sorts Sessions matching the sort order for this filter.
423      */

424     public Comparator JavaDoc<Session> getSortComparator() {
425         return new SessionComparator();
426     }
427
428     /**
429      * <p>Compares sessions according to sort fields.</p>
430      *
431      * @author Iain Shigeoka
432      */

433     private class SessionComparator implements Comparator JavaDoc {
434
435         /**
436          * <p>Compare two sessions according to sort order.</p>
437          *
438          * @param o1 The first session to compare
439          * @param o2 The second session to compare
440          * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
441          */

442         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
443             Session lhs = (Session)o1;
444             Session rhs = (Session)o2;
445             int comparison;
446             switch (sortField) {
447                 case SessionResultFilter.SORT_CREATION_DATE:
448                     comparison = lhs.getCreationDate().compareTo(rhs.getCreationDate());
449                     break;
450                 case SessionResultFilter.SORT_LAST_ACTIVITY_DATE:
451                     comparison = lhs.getLastActiveDate().compareTo(rhs.getCreationDate());
452                     break;
453                 case SessionResultFilter.SORT_NUM_CLIENT_PACKETS:
454                     comparison = (int)(lhs.getNumClientPackets() - rhs.getNumClientPackets());
455                     break;
456                 case SessionResultFilter.SORT_NUM_SERVER_PACKETS:
457                     comparison = (int)(lhs.getNumServerPackets() - rhs.getNumServerPackets());
458                     break;
459                 case SessionResultFilter.SORT_USER:
460                     // sort first by name, then by resource
461
comparison = compareString(lhs.getAddress().getNode(),
462                             rhs.getAddress().getNode());
463                     if (comparison == 0) {
464                         comparison = compareString(lhs.getAddress().getResource(),
465                                 rhs.getAddress().getResource());
466                     }
467                     break;
468                 default:
469                     comparison = 0;
470             }
471             if (sortOrder == SessionResultFilter.DESCENDING) {
472                 comparison *= -1; // Naturally ascending, flip sign if descending
473
}
474             return comparison;
475         }
476
477         private int compareString(String JavaDoc lhs, String JavaDoc rhs) {
478             if (lhs == null) {
479                 lhs = "";
480             }
481             if (rhs == null) {
482                 rhs = "";
483             }
484             return lhs.compareTo(rhs);
485         }
486     }
487
488     /**
489      * Rounds the given date down to the nearest specified second. The following
490      * table shows sample input and expected output values: (Note, only
491      * the time portion of the date is shown for brevity) <p>
492      * <p/>
493      * <table border="1">
494      * <tr>
495      * <th>Date</th><th>Seconds</th><th>Result</th>
496      * </tr>
497      * <tr>
498      * <td>1:37.48</td><td>5</td><td>1:37.45</td>
499      * </tr>
500      * <tr>
501      * <td>1:37.48</td><td>10</td><td>1:37.40</td>
502      * </tr>
503      * <tr>
504      * <td>1:37.48</td><td>30</td><td>1:37.30</td>
505      * </tr>
506      * <tr>
507      * <td>1:37.48</td><td>60</td><td>1:37.00</td>
508      * </tr>
509      * <tr>
510      * <td>1:37.48</td><td>120</td><td>1:36.00</td>
511      * </tr>
512      * </table><p>
513      * <p/>
514      * This method is useful when calculating the last post in
515      * a forum or the number of new messages from a given date. Using a rounded
516      * date allows Jive to internally cache the results of the date query.
517      * Here's an example that shows the last posted message in a forum accurate
518      * to the last 60 seconds: <p>
519      * <p/>
520      * <code>
521      * SessionResultFilter filter = new SessionResultFilter(); <br>
522      * filter.setSortOrder(SessionResultFilter.DESCENDING); <br>
523      * filter.setSortField(JiveGlobals.SORT_CREATION_DATE); <br>
524      * <b>filter.setCreationDateRangeMin(SessionResultFilter.roundDate(forum.getModificationDate(), 60));</b> <br>
525      * filter.setNumResults(1); <br>
526      * Iterator messages = forum.messages(filter); <br>
527      * ForumMessage lastPost = (ForumMessage)messages.next(); <br>
528      * </code><p>
529      *
530      * @param date the <tt>Date</tt> we want to round.
531      * @param seconds the number of seconds we want to round the date to.
532      * @return the given date, rounded down to the nearest specified number of seconds.
533      */

534     public static Date JavaDoc roundDate(Date JavaDoc date, int seconds) {
535         return new Date JavaDoc(roundDate(date.getTime(), seconds));
536     }
537
538     /**
539      * Rounds the given date down to the nearest specfied second.
540      *
541      * @param date the date (as a long) that we want to round.
542      * @param seconds the number of seconds we want to round the date to.
543      * @return the given date (as a long), rounded down to the nearest
544      * specified number of seconds.
545      */

546     public static long roundDate(long date, int seconds) {
547         return date - (date % (1000 * seconds));
548     }
549
550     /**
551      * Clones a SessionResultFilter
552      */

553     public Object JavaDoc clone() {
554         SessionResultFilter clonedFilter = new SessionResultFilter();
555         clonedFilter.setCreationDateRangeMax(getCreationDateRangeMax());
556         clonedFilter.setCreationDateRangeMin(getCreationDateRangeMin());
557         clonedFilter.setLastActivityDateRangeMax(getLastActivityDateRangeMax());
558         clonedFilter.setLastActivityDateRangeMin(getLastActivityDateRangeMin());
559         clonedFilter.setNumResults(getNumResults());
560         clonedFilter.setSortField(getSortField());
561         clonedFilter.setSortOrder(getSortOrder());
562         clonedFilter.setStartIndex(getStartIndex());
563         clonedFilter.setUsername(getUsername());
564         return clonedFilter;
565     }
566
567     public boolean equals(Object JavaDoc object) {
568         if (this == object) {
569             return true;
570         }
571         if (object != null && object instanceof SessionResultFilter) {
572             SessionResultFilter o = (SessionResultFilter)object;
573             return
574                     sortField == o.sortField &&
575                     sortOrder == o.sortOrder &&
576                     startIndex == o.startIndex &&
577                     numResults == o.numResults &&
578                     username == o.username &&
579                     ((creationDateRangeMin == null && o.creationDateRangeMin == null) ||
580                     creationDateRangeMin.equals(o.creationDateRangeMin)) &&
581                     ((creationDateRangeMax == null && o.creationDateRangeMax == null) ||
582                     creationDateRangeMax.equals(o.creationDateRangeMax)) &&
583                     ((lastActivityDateRangeMin == null && o.lastActivityDateRangeMin == null) ||
584                     lastActivityDateRangeMin.equals(o.lastActivityDateRangeMin)) &&
585                     ((lastActivityDateRangeMax == null && o.lastActivityDateRangeMax == null) ||
586                     lastActivityDateRangeMax.equals(o.lastActivityDateRangeMax));
587         }
588         else {
589             return false;
590         }
591     }
592 }
Popular Tags