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