001/*
002 * (C) Copyright 2013-2019 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Thomas Roger
018 */
019package org.nuxeo.ecm.platform.query.api;
020
021import java.io.Serializable;
022import java.util.List;
023import java.util.Map;
024
025import org.nuxeo.ecm.core.api.DocumentModel;
026import org.nuxeo.ecm.core.api.SortInfo;
027
028/**
029 * Basic interface for a page provider, independent of type of items in the list
030 * <p>
031 * Provides APIs to navigate between result pages
032 *
033 * @param <T> any Serializable item
034 * @since 5.4
035 * @author arussel
036 * @author Anahide Tchertchian
037 */
038public interface PageProvider<T> extends Serializable {
039
040    String DEFAULT_MAX_PAGE_SIZE_RUNTIME_PROP = "nuxeo.pageprovider.default-max-page-size";
041
042    /**
043     * Constant to express that the total number of result elements is unknown (usually because the query has not been
044     * done yet).
045     */
046    long UNKNOWN_SIZE = -1;
047
048    /**
049     * Constant to express that the total number of result elements is unknown even after performing a query.
050     *
051     * @since 5.5
052     */
053    long UNKNOWN_SIZE_AFTER_QUERY = -2;
054
055    /**
056     * Default maximum page size value.
057     *
058     * @since 6.0, default value is 1000.
059     */
060    long DEFAULT_MAX_PAGE_SIZE = 1000;
061
062    /**
063     * Page limit unknown.
064     *
065     * @since 5.8
066     */
067    long PAGE_LIMIT_UNKNOWN = -1;
068
069    /**
070     * Highlight context data property name. Used to store highlights in document context data when fetching ES results
071     *
072     * @since 9.1
073     */
074    String HIGHLIGHT_CTX_DATA = "highlight";
075
076    /**
077     * @since 10.2
078     */
079    String SKIP_AGGREGATES_PROP = "skipAggregates";
080
081    /**
082     * Returns the provider identifier
083     */
084    String getName();
085
086    /**
087     * Sets the provider identifier
088     */
089    void setName(String name);
090
091    /**
092     * Gets properties set on the provider.
093     * <p>
094     * Useful to retrieve a provider specific field attributes after instantiation. Other contextual parameters can be
095     * passed through API constructing the result provider.
096     */
097    Map<String, Serializable> getProperties();
098
099    /**
100     * Sets properties set on the provider.
101     * <p>
102     * Useful to initialize a provider specific field attributes after instantiation. Other contextual parameters can be
103     * passed through API constructing the result provider.
104     */
105    void setProperties(Map<String, Serializable> properties);
106
107    Object[] getParameters();
108
109    void setParameters(Object[] parameters);
110
111    /**
112     * Returns the number of results per page. 0 means no pagination unless {@link #getMaxPageSize()} is greater than
113     * this value, it will be taken into account instead.
114     */
115    long getPageSize();
116
117    /**
118     * Sets the number of results per page. 0 means no pagination unless {@link #getMaxPageSize()} is greater than this
119     * value, it will be taken into account instead.
120     */
121    void setPageSize(long pageSize);
122
123    /**
124     * Returns the max number of results per page. 0 means no pagination.
125     * <p>
126     * If page size is greater than this maximum value, it will be taken into account instead.
127     *
128     * @since 5.4.2
129     */
130    long getMaxPageSize();
131
132    /**
133     * Sets the max number of results per page. 0 means no pagination.
134     * <p>
135     * If page size is greater than this maximum value, it will be taken into account instead.
136     *
137     * @since 5.4.2
138     */
139    void setMaxPageSize(long pageSize);
140
141    /**
142     * Returns a list of available page size options to display in the page size selector.
143     * <p>
144     * Uses an hardcoded list of values, and adds up the page provider initial and current page sizes.
145     *
146     * @since 7.3
147     */
148    List<Long> getPageSizeOptions();
149
150    /**
151     * Sets the page size options.
152     *
153     * @since 7.3
154     */
155    void setPageSizeOptions(List<Long> options);
156
157    /**
158     * Returns the number of result elements if available or a negative value if it is unknown:
159     * <code>UNKNOWN_SIZE</code> if it is unknown as query was not done, and since 5.5,
160     * <code>UNKNOWN_SIZE_AFTER_QUERY</code> if it is still unknown after query was done.
161     */
162    long getResultsCount();
163
164    /**
165     * Sets the results count.
166     *
167     * @since 5.5
168     */
169    void setResultsCount(long resultsCount);
170
171    /**
172     * Returns the total number of pages or 0 if number of pages is unknown.
173     */
174    long getNumberOfPages();
175
176    /**
177     * Returns the page limit. The n first page we know they exist.
178     *
179     * @since 5.7.3
180     */
181    long getPageLimit();
182
183    /**
184     * Returns the current page of results.
185     * <p>
186     * This method is designed to be called from higher levels. It therefore ensures cheapness of repeated calls, rather
187     * than data consistency. There is a refresh() method for that.
188     * <p>
189     *
190     * @return the current page
191     */
192    List<T> getCurrentPage();
193
194    /**
195     * Returns the current page of results wrapped in a {@link PageSelection} item.
196     * <p>
197     * By default, no entry is selected, unless {@link #setSelectedEntries(List)} has been called before.
198     */
199    PageSelections<T> getCurrentSelectPage();
200
201    /**
202     * Sets the list of selected entries to take into account in {@link #getCurrentSelectPage()}.
203     */
204    void setSelectedEntries(List<T> entries);
205
206    /**
207     * Sets the current page offset.
208     * <p>
209     * If the provider keeps information linked to the current page, they should be reset after calling this method.
210     *
211     * @since 5.5
212     */
213    void setCurrentPageOffset(long offset);
214
215    /**
216     * Sets the current page of results to the required one.
217     *
218     * @param currentPageIndex the page index, starting from 0
219     * @since 5.7.3
220     */
221    void setCurrentPageIndex(long currentPageIndex);
222
223    /**
224     * Sets the current page of results to the required one and return it.
225     *
226     * @param page the page index, starting from 0
227     */
228    List<T> setCurrentPage(long page);
229
230    /**
231     * Forces refresh of the current page.
232     */
233    void refresh();
234
235    /**
236     * Returns a boolean expressing if there are further pages.
237     */
238    boolean isNextPageAvailable();
239
240    /**
241     * Returns a boolean expressing if the last page can be displayed.
242     *
243     * @since 5.5
244     */
245    boolean isLastPageAvailable();
246
247    /**
248     * Returns a boolean expressing if there is a previous page.
249     */
250    boolean isPreviousPageAvailable();
251
252    /**
253     * Returns the number of elements in current page.
254     */
255    long getCurrentPageSize();
256
257    /**
258     * Returns the offset (starting from 0) of the first element in the current page or <code>UNKNOWN_SIZE</code>.
259     */
260    long getCurrentPageOffset();
261
262    /**
263     * Returns the current page index as a zero-based integer.
264     */
265    long getCurrentPageIndex();
266
267    /**
268     * Returns a simple formatted string for current pagination status.
269     */
270    String getCurrentPageStatus();
271
272    /**
273     * Go to the first page
274     */
275    void firstPage();
276
277    /**
278     * Go to the previous page
279     */
280    void previousPage();
281
282    /**
283     * Go to the next page
284     */
285    void nextPage();
286
287    /**
288     * Go to the last page. Does not do anything if there is only one page displayed, or if the number of results is
289     * unknown.
290     */
291    void lastPage();
292
293    /**
294     * Returns the current entry.
295     */
296    T getCurrentEntry();
297
298    /**
299     * Sets the current entry.
300     */
301    void setCurrentEntry(T entry);
302
303    /**
304     * Sets the current entry index.
305     */
306    void setCurrentEntryIndex(long index);
307
308    /**
309     * Returns true if there is a next entry.
310     * <p>
311     * The next entry might be in next page, except if results count is unknown.
312     */
313    boolean isNextEntryAvailable();
314
315    /**
316     * Returns true if there is a previous entry.
317     * <p>
318     * The previous entry might be in previous page.
319     */
320    boolean isPreviousEntryAvailable();
321
322    /**
323     * Move the current entry to the previous one, if applicable.
324     * <p>
325     * No exception: this method is intended to be plugged directly at the UI layer. In case there's no previous entry,
326     * nothing will happen.
327     */
328    void previousEntry();
329
330    /**
331     * Move the current entry to the next one, if applicable.
332     * <p>
333     * If needed and possible, the provider will forward to next page. No special exceptions: this method is intended to
334     * be plugged directly at the UI layer. In case there's no next entry, nothing happens.
335     */
336    void nextEntry();
337
338    /**
339     * Returns if this provider is sortable
340     */
341    boolean isSortable();
342
343    void setSortable(boolean sortable);
344
345    /**
346     * Returns the complete list of sorting info for this provider
347     */
348    List<SortInfo> getSortInfos();
349
350    /**
351     * Returns the first sorting info for this provider
352     * <p>
353     * Also kept for compatibility with existing code.
354     */
355    SortInfo getSortInfo();
356
357    /**
358     * Sets the complete list of sorting info for this provider
359     */
360    void setSortInfos(List<SortInfo> sortInfo);
361
362    /**
363     * Sets the first and only sorting info for this provider.
364     * <p>
365     * Also kept for compatibility with existing code.
366     */
367    void setSortInfo(SortInfo sortInfo);
368
369    /**
370     * Sets the first and only sorting info for this provider if parameter removeOtherSortInfos is true. Otherwise, adds
371     * or changes the sortAscending information according to given direction.
372     */
373    void setSortInfo(String sortColumn, boolean sortAscending, boolean removeOtherSortInfos);
374
375    /**
376     * Add the given sort info to the list of sorting infos.
377     */
378    void addSortInfo(String sortColumn, boolean sortAscending);
379
380    /**
381     * Returns a positive 0-based integer if given sort information is found on the set sort infos, indicating the sort
382     * index, or -1 if this sort information is not found.
383     */
384    int getSortInfoIndex(String sortColumn, boolean sortAscending);
385
386    DocumentModel getSearchDocumentModel();
387
388    void setSearchDocumentModel(DocumentModel doc);
389
390    boolean hasError();
391
392    String getErrorMessage();
393
394    Throwable getError();
395
396    void setDefinition(PageProviderDefinition providerDefinition);
397
398    PageProviderDefinition getDefinition();
399
400    /**
401     * Sets the {@link PageProviderChangedListener} for this {@code PageProvider}.
402     *
403     * @since 5.7
404     */
405    void setPageProviderChangedListener(PageProviderChangedListener listener);
406
407    /**
408     * Test if provider parameters have changed
409     *
410     * @since 5.7
411     */
412    boolean hasChangedParameters(Object[] parameters);
413
414    /**
415     * @since 6.0
416     */
417    List<AggregateDefinition> getAggregateDefinitions();
418
419    /**
420     * @since 6.0
421     */
422    Map<String, Aggregate<? extends Bucket>> getAggregates();
423
424    /**
425     * @since 6.0
426     */
427    boolean hasAggregateSupport();
428
429    /**
430     * @since 10.2
431     */
432    boolean isSkipAggregates();
433
434    /**
435     * @since 8.4
436     */
437    List<QuickFilter> getQuickFilters();
438
439    /**
440     * @since 8.4
441     */
442    void setQuickFilters(List<QuickFilter> quickFilters);
443
444    /**
445     * @since 8.4
446     */
447    void addQuickFilter(QuickFilter quickFilter);
448
449    /**
450     * @since 8.4
451     */
452    List<QuickFilter> getAvailableQuickFilters();
453
454    /**
455     * @since 9.1
456     */
457    List<String> getHighlights();
458
459    /**
460     * @since 9.1
461     */
462    void setHighlights(List<String> highlights);
463
464    /**
465     * Limit of number of results beyond which the page provider may not be able to compute {@link #getResultsCount()}
466     * or navigate.
467     * <p>
468     * Requesting results beyond this limit may result in error. When {@link #getResultsCount()} is negative, it means
469     * there may be more results than this limit.
470     * <p>
471     * 0 means there is no limit.
472     *
473     * @since 9.3
474     */
475    long getResultsCountLimit();
476}