KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > josql > internal > Limit


1 /*
2  * Copyright 2004-2005 Gary Bentley
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may
5  * not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */

15 package org.josql.internal;
16
17 import java.util.List JavaDoc;
18 import java.util.ArrayList JavaDoc;
19
20 import org.josql.expressions.ValueExpression;
21
22 import org.josql.Query;
23 import org.josql.QueryParseException;
24 import org.josql.QueryExecutionException;
25
26 public class Limit
27 {
28
29     private ValueExpression start = null;
30     private ValueExpression rowsCount = null;
31
32     public Limit ()
33     {
34
35     }
36
37     public void init (Query q)
38                   throws QueryParseException
39     {
40
41     // Init the value expressions...
42
if (this.start != null)
43     {
44
45         this.start.init (q);
46
47         // Should probably check to ensure that accessors aren't used... since
48
// we don't have a "current object" to work on!.
49
Class JavaDoc c = this.start.getExpectedReturnType (q);
50
51         if (!Utilities.isNumber (c))
52         {
53
54         throw new QueryParseException ("The expected return type of the start expression: \"" +
55                            this.start +
56                            "\" of the LIMIT clause is: " +
57                            c.getName () +
58                            " however the expression when evaluated must return a numeric result.");
59
60         }
61
62     }
63
64     this.rowsCount.init (q);
65
66     // Should probably check to ensure that accessors aren't used... since
67
// we don't have a "current object" to work on!.
68

69     // Try and determine what the expected type is that we will return.
70
Class JavaDoc c = this.rowsCount.getExpectedReturnType (q);
71
72     if (!Utilities.isNumber (c))
73     {
74
75         throw new QueryParseException ("The expected return type of the rows count expression: \"" +
76                        this.rowsCount +
77                        "\" of the LIMIT clause is: " +
78                        c.getName () +
79                        " however the expression when evaluated must return a numeric result.");
80
81     }
82
83     }
84
85     public List JavaDoc getSubList (List JavaDoc objs,
86                 Query q)
87                         throws QueryExecutionException
88     {
89
90     // Get the row count.
91
Object JavaDoc o = this.rowsCount.evaluate (null,
92                         q);
93
94     int rows = -1;
95
96     // Ensure that it is a number.
97
if ((o != null)
98         &&
99         (!(o instanceof Number JavaDoc))
100        )
101     {
102
103         throw new QueryExecutionException ("Return value of rows count expression: \"" +
104                            this.rowsCount +
105                            "\" for the LIMIT clause is of type: " +
106                            o.getClass ().getName () +
107                            " expected it to return a numeric value.");
108
109     }
110
111     if (o != null)
112     {
113
114         // There are rounding issues here, but if the user provides a float/double value...
115
rows = ((Number JavaDoc) o).intValue ();
116
117     }
118
119     int start = 0;
120
121     // Now get the start value...
122
if (this.start != null)
123     {
124
125         Object JavaDoc s = this.start.evaluate (null,
126                         q);
127
128         // Ensure that it is a number.
129
if ((s != null)
130         &&
131         (!(s instanceof Number JavaDoc))
132            )
133         {
134
135         throw new QueryExecutionException ("Return value of the start expression: \"" +
136                            this.start +
137                            "\" for the LIMIT clause is of type: " +
138                            s.getClass ().getName () +
139                            " expected it to return a numeric value.");
140
141         }
142
143         if (s != null)
144         {
145
146         // There are rounding issues here, but if the user provides a float/double value...
147
start = ((Number JavaDoc) s).intValue ();
148
149         // Whilst for the user rows start at 1, for us they start at 0...
150
start--;
151
152         }
153
154     }
155
156     int ls = objs.size ();
157
158     // Now get our sub-list.
159
if (start > (ls - 1))
160     {
161
162         // Return nothing, outside of the range.
163
return new ArrayList JavaDoc ();
164
165     }
166
167     if (rows > 0)
168     {
169
170         if ((start + rows) > (ls - 1))
171         {
172
173             // Just return the rows starting at start...
174
// We return a new list to prevent issues with modifications...
175
return new ArrayList JavaDoc (objs.subList (start,
176                             ls));
177
178         }
179
180         // Here we return start + rows.
181
return new ArrayList JavaDoc (objs.subList (start,
182                         start + rows));
183
184     } else {
185
186         // Just ignore the rows...
187
return new ArrayList JavaDoc (objs.subList (start,
188                         ls));
189
190     }
191
192     }
193
194     public void setStart (ValueExpression v)
195     {
196
197     this.start = v;
198
199     }
200
201     public void setRowsCount (ValueExpression v)
202     {
203
204     this.rowsCount = v;
205
206     }
207
208 }
209
Popular Tags