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