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 }