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