1 /*
2 * The contents of this file are subject to the terms of the Common Development and
3 * Distribution License (the License). You may not use this file except in compliance with the
4 * License.
5 *
6 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7 * specific language governing permission and limitations under the License.
8 *
9 * When distributing Covered Software, include this CDDL Header Notice in each file and include
10 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11 * Header, with the fields enclosed by brackets [] replaced by your own identifying
12 * information: "Portions Copyright [year] [name of copyright owner]".
13 *
14 * Copyright 2012-2015 ForgeRock AS.
15 */
16
17 package org.forgerock.json.resource;
18
19 import java.util.List;
20 import java.util.Map;
21
22 import org.forgerock.http.routing.Version;
23 import org.forgerock.json.JsonPointer;
24 import org.forgerock.json.JsonValue;
25 import org.forgerock.util.i18n.PreferredLocales;
26 import org.forgerock.util.query.QueryFilter;
27
28 /**
29 * A request to search for all JSON resources matching a user specified set of criteria.
30 * <p>
31 * There are four types of query request: <ul> <li>default query: when neither a filter, expression or query ID are
32 * specified all resources will be returned <li>query by filter: returns all resources which match the {@link
33 * QueryFilters} specified using {@link #setQueryFilter(QueryFilter)} <li>query by ID: returns all resources which match
34 * the named prepared query specified using {@link #setQueryId(String)} <li>query by expression: returns all resources
35 * which match a native expression specified using {@link #setQueryExpression(String)}. Note that this type of query
36 * should only be used in very rare cases since it introduces a tight coupling between the application and the
37 * underlying JSON resource. In addition, applications should take care to prevent users from directly accessing this
38 * form of query for security reasons. </ul>
39 * <p>
40 * In addition to the above mentioned query types queries may also be paged when a page size is found via {@link
41 * #getPageSize()}. Paged requests should be used in most cases when an unknown number of query results will be
42 * returned.
43 */
44 public interface QueryRequest extends Request {
45 /**
46 * The name of the field which contains the paged results cookie in the JSON representation.
47 */
48 String FIELD_PAGED_RESULTS_COOKIE = "pagedResultsCookie";
49 /**
50 * The name of the field which contains the paged results offset in the JSON representation.
51 */
52 String FIELD_PAGED_RESULTS_OFFSET = "pagedResultsOffset";
53 /**
54 * The name of the field which contains the page size in the JSON representation.
55 */
56 String FIELD_PAGE_SIZE = "pageSize";
57 /**
58 * The name of the field which contains the query expression in the JSON representation.
59 */
60 String FIELD_QUERY_EXPRESSION = "queryExpression";
61 /**
62 * The name of the field which contains the query filter in the JSON representation.
63 */
64 String FIELD_QUERY_FILTER = "queryFilter";
65 /**
66 * The name of the field which contains the query ID in the JSON representation.
67 */
68 String FIELD_QUERY_ID = "queryId";
69 /**
70 * The name of the field which contains the sort keys in the JSON representation.
71 */
72 String FIELD_SORT_KEYS = "sortKeys";
73 /**
74 * The name of the field which contains the policy used for calculating the total number of paged results.
75 */
76 String FIELD_TOTAL_PAGED_RESULTS_POLICY = "totalPagedResultsPolicy";
77
78
79 @Override
80 <R, P> R accept(final RequestVisitor<R, P> v, final P p);
81
82
83 @Override
84 QueryRequest addField(JsonPointer... fields);
85
86
87 @Override
88 QueryRequest addField(String... fields);
89
90 /**
91 * Adds one or more sort keys which will be used for ordering the JSON resources returned by this query request.
92 *
93 * @param keys
94 * The sort keys which will be used for ordering the JSON resources returned by this query request.
95 * @return This query request.
96 * @throws UnsupportedOperationException
97 * If this query request does not permit changes to the sort keys.
98 */
99 QueryRequest addSortKey(SortKey... keys);
100
101 /**
102 * Adds one or more sort keys which will be used for ordering the JSON resources returned by this query request.
103 *
104 * @param keys
105 * The sort keys which will be used for ordering the JSON resources returned by this query request.
106 * @return This query request.
107 * @throws IllegalArgumentException
108 * If one or more of the provided sort keys could not be parsed.
109 * @throws UnsupportedOperationException
110 * If this query request does not permit changes to the sort keys.
111 */
112 QueryRequest addSortKey(String... keys);
113
114
115 @Override
116 String getAdditionalParameter(String name);
117
118
119 @Override
120 Map<String, String> getAdditionalParameters();
121
122
123 @Override
124 List<JsonPointer> getFields();
125
126 /**
127 * Returns the requested page results page size or {@code 0} if paged results are not required. For all paged result
128 * requests other than the initial request, a cookie should be provided with the query request. See {@link
129 * #getPagedResultsCookie()} for more information.
130 *
131 * @return The requested page results page size or {@code 0} if paged results are not required.
132 * @see #getPagedResultsCookie()
133 * @see #getPagedResultsOffset()
134 */
135 int getPageSize();
136
137 /**
138 * Returns the opaque cookie which is used by the resource provider to track its position in the set of query
139 * results. Paged results will be enabled if and only if the page size is non-zero.
140 * <p>
141 * The cookie must be {@code null} in the initial query request sent by the client. For subsequent query requests
142 * the client must include the cookie returned with the previous query result, until the resource provider returns a
143 * {@code null} cookie indicating that the final page of results has been returned.
144 * <p>
145 * <em>Note:</em> Cookies and offsets are mutually exclusive.
146 *
147 * @return The opaque cookie which is used by the resource provider to track its position in the set of query
148 * results, or {@code null} if paged results are not requested (when the page size is 0) or if the first page of
149 * results is being requested (when the page size is non-zero).
150 * @see #getPageSize()
151 * @see #getPagedResultsOffset()
152 */
153 String getPagedResultsCookie();
154
155 /**
156 * Returns the zero-based index of the first resource which should be included in the query results. An offset of 0
157 * (default) will return the first resource in the collection. An offset of {@code 1} will return the second, and so
158 * on ...
159 * <p>
160 * <em>Note:</em> Offsets and cookies are mutually exclusive. When a cookie is supplied only the default {@code 0}
161 * offset is supported.
162 * <p>
163 * Offset must be a zero-based integer denoting the number of records to skip. This is very similar to the
164 * <code>LIMIT</code> and <code>SKIP</code> clauses in SQL databases.
165 *
166 * @return The zero-based index within the result set of the first result which should be returned.
167 * @see #getPageSize()
168 * @see #getPagedResultsCookie()
169 */
170 int getPagedResultsOffset();
171
172
173 @Override
174 PreferredLocales getPreferredLocales();
175
176 /**
177 * Returns the native query expression which will be used for processing the query request. An example of a native
178 * query expression is a SQL statement.
179 * <p>
180 * <b>NOTE:</b> the native query expression, query filter, and query ID parameters are mutually exclusive and only
181 * one of them may be specified.
182 *
183 * @return The native query expression which will be used for processing the query request, or {@code null} if
184 * another type of query is to be performed.
185 * @see QueryRequest#getQueryFilter()
186 * @see QueryRequest#getQueryId()
187 */
188 String getQueryExpression();
189
190 /**
191 * Returns the query filter which will be used for selecting which JSON resources will be returned.
192 * <p>
193 * <b>NOTE:</b> the native query expression, query filter, and query ID parameters are mutually exclusive and only
194 * one of them may be specified.
195 *
196 * @return The query filter which will be used for selecting which JSON resources will be returned, or {@code null}
197 * if another type of query is to be performed.
198 * @see QueryRequest#getQueryExpression()
199 * @see QueryRequest#getQueryId()
200 */
201 QueryFilter<JsonPointer> getQueryFilter();
202
203 /**
204 * Returns the query identifier for pre-defined queries.
205 * <p>
206 * <b>NOTE:</b> the native query expression, query filter, and query ID parameters are mutually exclusive and only
207 * one of them may be specified.
208 *
209 * @return The query identifier for pre-defined queries, or {@code null} if a pre-defined query is not to be used,
210 * or {@code null} if another type of query is to be performed.
211 * @see QueryRequest#getQueryExpression()
212 * @see QueryRequest#getQueryFilter()
213 */
214 String getQueryId();
215
216
217 @Override
218 RequestType getRequestType();
219
220 @Override
221 String getResourcePath();
222
223 @Override
224 ResourcePath getResourcePathObject();
225
226 @Override
227 Version getResourceVersion();
228
229 /**
230 * Returns the sort keys which should be used for ordering the JSON resources returned by this query request. The
231 * returned list may be modified if permitted by this query request.
232 *
233 * @return The sort keys which should be used for ordering the JSON resources returned by this query request (never
234 * {@code null}).
235 */
236 List<SortKey> getSortKeys();
237
238 /**
239 * Returns the {@link CountPolicy} used to calculate {@link QueryResponse#getTotalPagedResults()}.
240 *
241 * @return The count policy.
242 * @see QueryResponse#getTotalPagedResults()
243 */
244 CountPolicy getTotalPagedResultsPolicy();
245
246 @Override
247 QueryRequest setAdditionalParameter(String name, String value) throws BadRequestException;
248
249 /**
250 * Sets the requested page results page size or {@code 0} if paged results are not required. For all paged result
251 * requests other than the initial request, a cookie should be provided with the query request. See {@link
252 * #setPagedResultsCookie(String)} for more information.
253 *
254 * @param size
255 * The requested page results page size or {@code 0} if paged results are not required.
256 * @return This query request.
257 * @throws UnsupportedOperationException
258 * If this query request does not permit changes to the page size.
259 * @see #getPagedResultsCookie()
260 * @see #setPagedResultsOffset(int)
261 */
262 QueryRequest setPageSize(int size);
263
264 /**
265 * Sets the opaque cookie which is used by the resource provider to track its position in the set of query results.
266 * Paged results will be enabled if and only if the page size is non-zero.
267 * <p>
268 * The cookie must be {@code null} in the initial query request sent by the client. For subsequent query requests
269 * the client must include the cookie returned with the previous query result, until the resource provider returns a
270 * {@code null} cookie indicating that the final page of results has been returned.
271 * <p>
272 * When subsequent paged requests are being made no query parameters may be altered; doing so will result in
273 * undefined behavior. The only parameter that may be changed during paged requests is the page size.
274 *
275 * @param cookie
276 * The opaque cookie which is used by the resource provider to track its position in the set of query
277 * results.
278 * @return This query request.
279 * @throws UnsupportedOperationException
280 * If this query request does not permit changes to the paged results cookie.
281 * @see #setPageSize(int)
282 * @see #addSortKey(SortKey...)
283 * @see #addSortKey(String...)
284 */
285 QueryRequest setPagedResultsCookie(String cookie);
286
287 /**
288 * Sets the zero-based index of the first resource which should be included in the query results. An offset of 0
289 * (default) will return the first resource in the collection. An offset of {@code 1} will return the second, and so
290 * on ...
291 * <p>
292 * <em>Note:</em> Offsets and cookies are mutually exclusive. When a cookie is supplied only the default {@code 0}
293 * offset is supported.
294 * <p>
295 * Offset must be a zero-based integer denoting the number of records to skip. This is very similar to the
296 * <code>LIMIT</code> and <code>SKIP</code> clauses in SQL databases.
297 *
298 * @param offset
299 * The index within the result set of the first result which should be returned.
300 * @return This query request.
301 * @throws UnsupportedOperationException
302 * If this query request does not permit changes to the paged results offset.
303 * @see #setPageSize(int)
304 * @see #setPagedResultsCookie(String)
305 */
306 QueryRequest setPagedResultsOffset(int offset);
307
308 @Override
309 QueryRequest setPreferredLocales(PreferredLocales preferredLocales);
310
311 /**
312 * Sets the native query expression which will be used for processing the query request. An example of a native
313 * query expression is a SQL statement.
314 * <p>
315 * <b>NOTE:</b> the native query expression, query filter, and query ID parameters are mutually exclusive and only
316 * one of them may be specified.
317 *
318 * @param expression
319 * The native query expression which will be used for processing the query request, or {@code null} if
320 * another type of query is to be performed.
321 * @return This query request.
322 * @throws UnsupportedOperationException
323 * If this query request does not permit changes to the query identifier.
324 * @see QueryRequest#setQueryFilter(QueryFilter)
325 * @see QueryRequest#setQueryId(String)
326 */
327 QueryRequest setQueryExpression(String expression);
328
329 /**
330 * Sets the query filter which will be used for selecting which JSON resources will be returned.
331 * <p>
332 * <b>NOTE:</b> the native query expression, query filter, and query ID parameters are mutually exclusive and only
333 * one of them may be specified.
334 *
335 * @param filter
336 * The query filter which will be used for selecting which JSON resources will be returned, or {@code null}
337 * if another type of query is to be performed.
338 * @return This query request.
339 * @throws UnsupportedOperationException
340 * If this query request does not permit changes to the query filter.
341 * @see QueryRequest#setQueryExpression(String)
342 * @see QueryRequest#setQueryId(String)
343 */
344 QueryRequest setQueryFilter(QueryFilter<JsonPointer> filter);
345
346 /**
347 * Sets the query identifier for pre-defined queries.
348 * <p>
349 * <b>NOTE:</b> the native query expression, query filter, and query ID parameters are mutually exclusive and only
350 * one of them may be specified.
351 *
352 * @param id
353 * The query identifier for pre-defined queries, or {@code null} if another type of query is to be
354 * performed.
355 * @return This query request.
356 * @throws UnsupportedOperationException
357 * If this query request does not permit changes to the query identifier.
358 * @see QueryRequest#setQueryExpression(String)
359 * @see QueryRequest#setQueryFilter(QueryFilter)
360 */
361 QueryRequest setQueryId(String id);
362
363 @Override
364 QueryRequest setResourcePath(ResourcePath path);
365
366 @Override
367 QueryRequest setResourcePath(String path);
368
369 @Override
370 QueryRequest setResourceVersion(Version resourceVersion);
371
372 /**
373 * Sets the policy for calculating the total number of paged results. If no count policy is supplied or paged
374 * results are not requested a default of {@link CountPolicy#NONE} will be used. This will result in no count being
375 * performed and no overhead incurred.
376 *
377 * @param policy
378 * The policy used to calculate total paged results
379 * @return This query request.
380 * @see QueryResponse#getTotalPagedResultsPolicy()
381 * @see QueryResponse#getTotalPagedResults()
382 */
383 QueryRequest setTotalPagedResultsPolicy(CountPolicy policy);
384
385 @Override
386 JsonValue toJsonValue();
387 }