001/*
002 * (C) Copyright 2014 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 *     Anahide Tchertchian
018 *     Benoit Delbosc
019 */
020package org.nuxeo.ecm.platform.query.core;
021
022
023import org.nuxeo.common.xmap.annotation.XNode;
024import org.nuxeo.common.xmap.annotation.XNodeList;
025import org.nuxeo.common.xmap.annotation.XNodeMap;
026import org.nuxeo.ecm.core.api.SortInfo;
027import org.nuxeo.ecm.platform.query.api.AggregateDefinition;
028import org.nuxeo.ecm.platform.query.api.QuickFilter;
029import org.nuxeo.ecm.platform.query.api.WhereClauseDefinition;
030
031import java.util.ArrayList;
032import java.util.Arrays;
033import java.util.Collections;
034import java.util.HashMap;
035import java.util.List;
036import java.util.Map;
037
038/**
039 * Base class for page provider descriptors.
040 *
041 * @since 6.0
042 */
043public abstract class BasePageProviderDescriptor {
044
045    @XNode("@name")
046    protected String name;
047
048    @XNode("@enabled")
049    protected boolean enabled = true;
050
051    @XNodeMap(value = "property", key = "@name", type = HashMap.class, componentType = String.class)
052    protected Map<String, String> properties = new HashMap<>();
053
054    @XNodeList(value = "parameter", type = String[].class, componentType = String.class)
055    protected String[] queryParameters;
056
057    @XNode("pageSize")
058    protected long pageSize = 0;
059
060    @XNode("pageSizeBinding")
061    protected String pageSizeBinding;
062
063    @XNode("maxPageSize")
064    protected Long maxPageSize;
065
066    /**
067     * @since 7.3
068     */
069    @XNodeList(value = "pageSizeOptions/option", type = ArrayList.class, componentType = Long.class)
070    protected List<Long> pageSizeOptions;
071
072    @XNode("sortable")
073    protected boolean sortable = true;
074
075    @XNodeList(value = "sort", type = ArrayList.class, componentType = SortInfoDescriptor.class)
076    protected List<SortInfoDescriptor> sortInfos;
077
078    @XNode("sortInfosBinding")
079    protected String sortInfosBinding;
080
081    protected String pattern;
082
083    @XNode("pattern@quoteParameters")
084    protected boolean quotePatternParameters = true;
085
086    @XNode("pattern@escapeParameters")
087    protected boolean escapePatternParameters = true;
088
089    @XNode("whereClause")
090    protected WhereClauseDescriptor whereClause;
091
092    /**
093     * @since 6.0
094     */
095    @XNode("searchDocumentType")
096    protected String searchDocumentType;
097
098    /**
099     * @since 8.4
100     */
101    @XNodeList(value = "quickFilters/quickFilter", componentType = QuickFilterDescriptor.class, type = ArrayList.class)
102    protected List<QuickFilterDescriptor> quickFilters;
103
104    @XNode("pattern")
105    public void setPattern(String pattern) {
106        // remove new lines and following spaces
107        if (pattern != null) {
108            this.pattern = pattern.replaceAll("\r?\n\\s*", " ");
109        }
110    }
111
112    /**
113     * @since 6.0
114     */
115    @XNodeList(value = "aggregates/aggregate", type = ArrayList.class, componentType = AggregateDescriptor.class)
116    protected List<AggregateDescriptor> aggregates;
117
118    /**
119     * @since 7.4
120     */
121    @XNode("trackUsage")
122    protected boolean trackUsage = false;
123
124    /**
125     * @since 7.4
126     */
127    public boolean isUsageTrackingEnabled() {
128        return trackUsage;
129    }
130
131    public boolean getQuotePatternParameters() {
132        return quotePatternParameters;
133    }
134
135    public boolean getEscapePatternParameters() {
136        return escapePatternParameters;
137    }
138
139    public Map<String, String> getProperties() {
140        return properties;
141    }
142
143    public String[] getQueryParameters() {
144        return queryParameters;
145    }
146
147    public String getPattern() {
148        return pattern;
149    }
150
151    public WhereClauseDefinition getWhereClause() {
152        return whereClause;
153    }
154
155    /**
156     * @since 8.4
157     */
158    public List<QuickFilter> getQuickFilters() {
159        return (List<QuickFilter>) (List<?>) quickFilters;
160    }
161
162    public boolean isSortable() {
163        return sortable;
164    }
165
166    public List<SortInfo> getSortInfos() {
167        List<SortInfo> res = new ArrayList<>();
168        if (sortInfos != null) {
169            for (SortInfoDescriptor sortInfo : sortInfos) {
170                res.add(sortInfo.getSortInfo());
171            }
172        }
173        return res;
174    }
175
176    public long getPageSize() {
177        return pageSize;
178    }
179
180    public List<Long> getPageSizeOptions() {
181        List<Long> res = new ArrayList<>();
182        if (pageSizeOptions == null || pageSizeOptions.isEmpty()) {
183            res.addAll(Arrays.asList(5L, 10L, 20L, 30L, 40L, 50L));
184        } else {
185            res.addAll(pageSizeOptions);
186        }
187        long defaultPageSize = getPageSize();
188        if (!res.contains(defaultPageSize)) {
189            res.add(defaultPageSize);
190        }
191        Collections.sort(res);
192        return res;
193    }
194
195    public boolean isEnabled() {
196        return enabled;
197    }
198
199    public void setEnabled(boolean enabled) {
200        this.enabled = enabled;
201    }
202
203    public String getPageSizeBinding() {
204        return pageSizeBinding;
205    }
206
207    public String getSortInfosBinding() {
208        return sortInfosBinding;
209    }
210
211    public String getName() {
212        return name;
213    }
214
215    public void setName(String name) {
216        this.name = name;
217    }
218
219    public Long getMaxPageSize() {
220        return maxPageSize;
221    }
222
223    /**
224     * @since 7.10
225     */
226    public void setQuotePatternParameters(boolean quotePatternParameters) {
227        this.quotePatternParameters = quotePatternParameters;
228    }
229
230    /**
231     * @since 7.10
232     */
233    public void setEscapePatternParameters(boolean escapePatternParameters) {
234        this.escapePatternParameters = escapePatternParameters;
235    }
236
237    /**
238     * @since 6.0
239     */
240    @SuppressWarnings("unchecked")
241    public List<AggregateDefinition> getAggregates() {
242        return (List<AggregateDefinition>) (List<?>) aggregates;
243    }
244
245    /**
246     * Returns the search document type used for wher clause, aggregates and named parameters.
247     *
248     * @since 6.0
249     */
250    public String getSearchDocumentType() {
251        if (searchDocumentType == null) {
252            // BBB
253            WhereClauseDefinition wc = getWhereClause();
254            if (wc != null) {
255                return wc.getDocType();
256            }
257        }
258        return searchDocumentType;
259    }
260
261    protected BasePageProviderDescriptor cloneDescriptor() {
262        BasePageProviderDescriptor clone = newInstance();
263        clone.name = getName();
264        clone.enabled = isEnabled();
265        Map<String, String> props = getProperties();
266        if (props != null) {
267            clone.properties = new HashMap<>();
268            clone.properties.putAll(props);
269        }
270        String[] params = getQueryParameters();
271        if (params != null) {
272            clone.queryParameters = params.clone();
273        }
274        clone.pageSize = getPageSize();
275        clone.pageSizeBinding = getPageSizeBinding();
276        clone.maxPageSize = getMaxPageSize();
277        clone.pageSizeOptions = getPageSizeOptions();
278        clone.sortable = isSortable();
279        if (sortInfos != null) {
280            clone.sortInfos = new ArrayList<>();
281            for (SortInfoDescriptor item : sortInfos) {
282                clone.sortInfos.add(item.clone());
283            }
284        }
285        clone.sortInfosBinding = getSortInfosBinding();
286        clone.pattern = getPattern();
287        clone.quotePatternParameters = getQuotePatternParameters();
288        clone.escapePatternParameters = getEscapePatternParameters();
289        if (whereClause != null) {
290            clone.whereClause = whereClause.clone();
291        }
292        if (quickFilters != null) {
293            clone.quickFilters = new ArrayList<>();
294            for (QuickFilterDescriptor quickFilter : quickFilters) {
295                clone.quickFilters.add(quickFilter.clone());
296            }
297        }
298        if (aggregates != null) {
299            clone.aggregates = new ArrayList<>();
300            for (AggregateDescriptor agg : aggregates) {
301                clone.aggregates.add(agg.clone());
302            }
303        }
304        clone.searchDocumentType = searchDocumentType;
305        clone.trackUsage = trackUsage;
306        return clone;
307    }
308
309    protected abstract BasePageProviderDescriptor newInstance();
310
311}