View Javadoc
1   /**
2    * Copyright 2014 Internet2
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  /*
17   * @author mchyzer
18   * $Id: QueryOptions.java,v 1.3 2009-04-14 07:41:24 mchyzer Exp $
19   */
20  package edu.internet2.middleware.grouper.internal.dao;
21  
22  import org.apache.commons.lang.StringUtils;
23  
24  import edu.internet2.middleware.grouper.util.GrouperUtil;
25  
26  /**
27   * <pre>
28   * options on a query (e.g. sorting, paging, total result size, etc)
29   * 
30   * Sorting example:
31   *    queryOptions = new QueryOptions().sortAsc("m.subjectIdDb");
32   *
33   *    Set&lt;Member&gt; members = group.getImmediateMembers(field, queryOptions);
34   *
35   * Paging example:
36   *    QueryPaging queryPaging = new QueryPaging();
37   *    queryPaging.setPageSize(pageSize);
38   *    queryPaging.setPageNumber(pageNumberOneIndexed);
39   *    -or- queryPaging.setFirstIndexOnPage(startZeroIndexed);
40   *    queryOptions = new QueryOptions().paging(queryPaging);
41   *
42   *    Set&lt;Member&gt; members = group.getImmediateMembers(field, queryOptions);
43   *
44   * Query count example:
45   * 
46   *    QueryOptions queryOptions = new QueryOptions().retrieveCount(true).retrieveResults(false);
47   *    group.getImmediateMembers(field, queryOptions);
48   *    int totalSize = queryOptions.getCount().intValue();
49   * 
50   * </pre>
51   */
52  public class QueryOptions {
53  
54    /**
55     * see if paging is constraining the query so we dont need a separate count query
56     * @param queryOptions
57     * @param maxResults
58     * @return true if needs extra count query
59     */
60    public static boolean needsCountQuery(QueryOptions queryOptions, int maxResults) {
61      
62      if (queryOptions == null) {
63        return true;
64      }
65  
66      QueryPaging queryPaging = queryOptions.getQueryPaging();
67      if (queryPaging == null) {
68        return true;
69      }
70      
71      return queryPaging.getPageSize() > maxResults;
72    }
73    
74    /**
75     * 
76     * @param queryOptions
77     */
78    public static void initTotalCount(QueryOptions queryOptions) {
79      if (queryOptions == null) {
80        return;
81      }
82      if (queryOptions.getQueryPaging() != null && queryOptions.getQueryPaging().isDoTotalCount()) {
83        queryOptions.getQueryPaging().setTotalRecordCount(0);
84      }
85      if (queryOptions.isRetrieveCount()) {
86        queryOptions.setCount(0L);
87      }
88    }
89    
90    /**
91     * 
92     */
93    public QueryOptions() {
94      
95    }
96    
97    /**
98     * @param sortString 
99     * @param ascending 
100    * @param pageNumber 1 indexed page number
101    * @param pageSize 
102    * @return the query options if needed
103    * 
104    */
105   public static QueryOptions create(String sortString, Boolean ascending, Integer pageNumber, Integer pageSize) {
106     QueryOptions queryOptions = null;
107     
108     if (ascending != null || !StringUtils.isBlank(sortString) 
109         || pageNumber != null || pageSize != null) {
110       
111       queryOptions = new QueryOptions();
112       
113       if (ascending != null || !StringUtils.isBlank(sortString)) {
114         
115         QuerySortuper/internal/dao/QuerySort.html#QuerySort">QuerySort querySort = new QuerySort(sortString, GrouperUtil.defaultIfNull(ascending, Boolean.TRUE));
116         queryOptions.sort(querySort);
117         
118       }
119 
120       if (pageNumber != null || pageSize != null) {
121         
122         QueryPaging/internal/dao/QueryPaging.html#QueryPaging">QueryPaging queryPaging = new QueryPaging();
123         queryPaging.setPageNumber(pageNumber);
124         queryPaging.setPageSize(pageSize);
125         queryOptions.paging(queryPaging);
126       }
127       
128     }
129     return queryOptions;
130   }
131   
132   /**
133    * if this query is sorted (by options), and what the col(s) are
134    */
135   private QuerySort querySort;
136 
137   /**
138    * If this is a paged query, and what are specs
139    */
140   private QueryPaging queryPaging;
141   
142   /**
143    * If the results should be retrieved (generally only false for size queries).
144    * default to true
145    */
146   private Boolean retrieveResults;
147   
148   /**
149    * If the count of the query should be retrieved (sometimes paging will get
150    * the count)
151    * default to false
152    */
153   private Boolean retrieveCount;
154   
155   /**
156    * if hibernate should second level cache this query
157    */
158   private Boolean secondLevelCache;
159   
160   /**
161    * if hibernate should second level cache this query, this is the region
162    */
163   private String secondLevelCacheRegion;
164   
165   /**
166    * 
167    * @param secondLevelCache1
168    * @return this for chaining
169    */
170   public QueryOptions secondLevelCache(boolean secondLevelCache1) {
171     this.secondLevelCache = secondLevelCache1;
172     return this;
173   }
174   
175   /**
176    * 
177    * @return if second level cache
178    */
179   public Boolean getSecondLevelCache() {
180     return this.secondLevelCache;
181   }
182   
183   /**
184    * 
185    * @param secondLevelCacheRegion1
186    * @return this for chaining
187    */
188   public QueryOptions secondLevelCacheRegion(String secondLevelCacheRegion1) {
189     this.secondLevelCacheRegion = secondLevelCacheRegion1;
190     return this;
191   }
192   
193   /**
194    * 
195    * @return if second level cache
196    */
197   public String getSecondLevelCacheRegion() {
198     return this.secondLevelCacheRegion;
199   }
200   
201   /**
202    * count of the query if it is being calculated.  Note the hibernateSession API
203    * is what sets this
204    */
205   private Long count = null;
206   
207   /**
208    * 
209    * @see java.lang.Object#toString()
210    */
211   @Override
212   public String toString() {
213     StringBuilder result = new StringBuilder("QueryOptions: ");
214     if (this.queryPaging != null) {
215       result.append("queryPaging: ").append(queryPaging.toString()).append(", ");
216     }
217     if (this.querySort != null) {
218       result.append("querySort: ").append(querySort.sortString(false)).append(", ");
219     }
220     if (this.secondLevelCache != null) {
221       result.append("secondLevelCache: ").append(this.getSecondLevelCache()).append(", ");
222     }
223     if (this.retrieveResults != null) {
224       result.append("retrieveResults: ").append(this.retrieveResults).append(", ");
225     }
226     if (this.retrieveCount != null) {
227       result.append("retrieveCount: ").append(retrieveCount).append(", ");
228     }
229     if (this.count != null) {
230       result.append("count: ").append(this.count).append(", ");
231     }
232     return result.toString();
233   }
234 
235   /**
236    * if this query is sorted (by options), and what the col(s) are
237    * @return sort
238    */
239   public QuerySort getQuerySort() {
240     return this.querySort;
241   }
242 
243   /**
244    * if this query is sorted (by options), and what the col(s) are
245    * @param querySort1
246    * @return this for chaining
247    */
248   public QueryOptions sort(QuerySort querySort1) {
249     this.querySort = querySort1;
250     return this;
251   }
252 
253   /**
254    * If this is a paged query, and what are specs
255    * @return paging
256    */
257   public QueryPaging getQueryPaging() {
258     return this.queryPaging;
259   }
260 
261   /**
262    * sort ascending on this field
263    * @param field
264    * @return this for chaining
265    */
266   public QueryOptions sortAsc(String field) {
267     if (this.querySort == null) {
268       this.querySort = new QuerySort(field, true);
269     } else {
270       this.querySort.insertSortToBeginning(field, true);
271     }
272     return this;
273   }
274 
275   /**
276    * factory for query paging
277    * @param pageSize
278    * @param pageNumber 1 indexed page number
279    * @param doTotalCount true to do total count, false to not
280    * @return this for chaining
281    */
282   public QueryOptions paging(int pageSize, int pageNumber, boolean doTotalCount) {
283     this.queryPaging = QueryPaging.page(pageSize, pageNumber, doTotalCount);
284     return this;
285   }
286   
287   /**
288    * factory for query paging
289    * @param pageSize
290    * @param lastCursorField 
291    * @param cursorFieldIncludesLastRetrieved 
292    * @param doTotalCount true to do total count, false to not
293    * @return this for chaining
294    */
295   public QueryOptions pagingCursor(int pageSize, Object lastCursorField, boolean cursorFieldIncludesLastRetrieved, boolean doTotalCount) {
296     this.queryPaging = QueryPaging.pageCursor(pageSize, lastCursorField, cursorFieldIncludesLastRetrieved, doTotalCount);
297     return this;
298   }
299   
300   /**
301    * sort ascending on this field
302    * @param field
303    * @return this for chaining
304    */
305   public QueryOptions sortDesc(String field) {
306     if (this.querySort == null) {
307       this.querySort = new QuerySort(field, false);
308     } else {
309       this.querySort.insertSortToBeginning(field, false);
310     }
311     return this;
312   }
313   
314   /**
315    * If this is a paged query, and what are specs
316    * @param queryPaging1
317    * @return this for chaining
318    */
319   public QueryOptions paging(QueryPaging queryPaging1) {
320     this.queryPaging = queryPaging1;
321     return this;
322   }
323 
324   /**
325    * If the results should be retrieved (generally only false for size queries).
326    * default to true
327    * @return retrieve results
328    */
329   public boolean isRetrieveResults() {
330     return this.retrieveResults == null ? true : this.retrieveResults;
331   }
332 
333   /**
334    * If the results should be retrieved (generally only false for size queries).
335    * default to true
336    * @param retrieveResults1
337    * @return this for chaining
338    */
339   public QueryOptions retrieveResults(boolean retrieveResults1) {
340     this.retrieveResults = retrieveResults1;
341     return this;
342   }
343 
344   /**
345    * If the count of the query should be retrieved (sometimes paging will get
346    * the count)
347    * default to false
348    * @return retrieve count
349    */
350   public boolean isRetrieveCount() {
351     return this.retrieveCount == null ? false : this.retrieveCount;
352   }
353 
354   /**
355    * If the count of the query should be retrieved (sometimes paging will get
356    * the count)
357    * default to false
358    * @param retrieveCount1
359    * @return this for chaining
360    */
361   public QueryOptions retrieveCount(boolean retrieveCount1) {
362     this.retrieveCount = retrieveCount1;
363     return this;
364   }
365 
366   /**
367    * count of the query if it is being calculated.  Note the hibernateSession API
368    * is what sets this
369    * @return the count or null if not set
370    */
371   public Long getCount() {
372     return this.count;
373   }
374 
375   /**
376    * count of the query if it is being calculated.  Note the hibernateSession API
377    * is what sets this
378    * @param count1
379    */
380   public void setCount(Long count1) {
381     this.count = count1;
382   }
383   
384 }