1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.kernel.dao.orm;
24  
25  import com.liferay.portal.kernel.log.Log;
26  import com.liferay.portal.kernel.log.LogFactoryUtil;
27  import com.liferay.portal.kernel.util.OrderByComparator;
28  import com.liferay.portal.kernel.util.Randomizer;
29  
30  import java.util.ArrayList;
31  import java.util.Iterator;
32  import java.util.List;
33  
34  /**
35   * <a href="QueryUtil.java.html"><b><i>View Source</i></b></a>
36   *
37   * @author Brian Wing Shun Chan
38   *
39   */
40  public class QueryUtil {
41  
42      public static final int ALL_POS = -1;
43  
44      public static Iterator<?> iterate(
45          Query query, Dialect dialect, int start, int end) {
46  
47          return list(query, dialect, start, end).iterator();
48      }
49  
50      public static List<?> list(
51          Query query, Dialect dialect, int start, int end) {
52  
53          if ((start == ALL_POS) && (end == ALL_POS)) {
54              return query.list();
55          }
56          else {
57              if (dialect.supportsLimit()) {
58                  query.setMaxResults(end - start);
59                  query.setFirstResult(start);
60  
61                  return query.list();
62              }
63              else {
64                  List<Object> list = new ArrayList<Object>();
65  
66                  ScrollableResults sr = query.scroll();
67  
68                  if (sr.first() && sr.scroll(start)) {
69                      for (int i = start; i < end; i++) {
70                          Object obj = sr.get(0);
71  
72                          list.add(obj);
73  
74                          if (!sr.next()) {
75                              break;
76                          }
77                      }
78                  }
79  
80                  return list;
81              }
82          }
83      }
84  
85      public static List<?> randomList(
86          Query query, Dialect dialect, int total, int num) {
87  
88          if ((total == 0) || (num == 0)) {
89              return new ArrayList<Object>();
90          }
91  
92          if (num >= total) {
93              return list(query, dialect, ALL_POS, ALL_POS);
94          }
95  
96          int[] scrollIds = Randomizer.getInstance().nextInt(total, num);
97  
98          List<Object> list = new ArrayList<Object>();
99  
100         ScrollableResults sr = query.scroll();
101 
102         for (int i = 0; i < scrollIds.length; i++) {
103             if (sr.scroll(scrollIds[i])) {
104                 Object obj = sr.get(0);
105 
106                 list.add(obj);
107 
108                 sr.first();
109             }
110         }
111 
112         return list;
113     }
114 
115     public static Comparable<?>[] getPrevAndNext(
116         Query query, int count, OrderByComparator obc,
117         Comparable<?> comparable) {
118 
119         int pos = count;
120         int boundary = 0;
121 
122         Comparable<?>[] array = new Comparable[3];
123 
124         ScrollableResults sr = query.scroll();
125 
126         if (sr.first()) {
127             while (true) {
128                 Object obj = sr.get(0);
129 
130                 if (obj == null) {
131                     if (_log.isWarnEnabled()) {
132                         _log.warn("Object is null");
133                     }
134 
135                     break;
136                 }
137 
138                 Comparable<?> curComparable = (Comparable<?>)obj;
139 
140                 int value = obc.compare(comparable, curComparable);
141 
142                 if (_log.isDebugEnabled()) {
143                     _log.debug("Comparison result is " + value);
144                 }
145 
146                 if (value == 0) {
147                     if (!comparable.equals(curComparable)) {
148                         break;
149                     }
150 
151                     array[1] = curComparable;
152 
153                     if (sr.previous()) {
154                         array[0] = (Comparable<?>)sr.get(0);
155                     }
156 
157                     sr.next();
158 
159                     if (sr.next()) {
160                         array[2] = (Comparable<?>)sr.get(0);
161                     }
162 
163                     break;
164                 }
165 
166                 if (pos == 1) {
167                     break;
168                 }
169 
170                 pos = (int)Math.ceil(pos / 2.0);
171 
172                 int scrollPos = pos;
173 
174                 if (value < 0) {
175                     scrollPos = scrollPos * -1;
176                 }
177 
178                 boundary += scrollPos;
179 
180                 if (boundary < 0) {
181                     scrollPos = scrollPos + (boundary * -1) + 1;
182 
183                     boundary = 0;
184                 }
185 
186                 if (boundary > count) {
187                     scrollPos = scrollPos - (boundary - count);
188 
189                     boundary = scrollPos;
190                 }
191 
192                 if (_log.isDebugEnabled()) {
193                     _log.debug("Scroll " + scrollPos);
194                 }
195 
196                 if (!sr.scroll(scrollPos)) {
197                     if (value < 0) {
198                         if (!sr.next()) {
199                             break;
200                         }
201                     }
202                     else {
203                         if (!sr.previous()) {
204                             break;
205                         }
206                     }
207                 }
208             }
209         }
210 
211         return array;
212     }
213 
214     private static Log _log = LogFactoryUtil.getLog(QueryUtil.class);
215 
216 }