View Javadoc
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 }