001/*
002 * (C) Copyright 2006-2018 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 *      Vladimir Pasquier <vpasquier@nuxeo.com>
018 */
019package org.nuxeo.ecm.automation.core.operations.services.query;
020
021import org.nuxeo.ecm.automation.OperationException;
022import org.nuxeo.ecm.automation.core.Constants;
023import org.nuxeo.ecm.automation.core.annotations.Context;
024import org.nuxeo.ecm.automation.core.annotations.Operation;
025import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
026import org.nuxeo.ecm.automation.core.annotations.Param;
027import org.nuxeo.ecm.automation.core.util.PageProviderHelper;
028import org.nuxeo.ecm.automation.core.util.Properties;
029import org.nuxeo.ecm.automation.core.util.StringList;
030import org.nuxeo.ecm.automation.jaxrs.io.documents.PaginableDocumentModelListImpl;
031import org.nuxeo.ecm.core.api.CoreSession;
032import org.nuxeo.ecm.core.api.DocumentModel;
033import org.nuxeo.ecm.core.api.DocumentModelList;
034import org.nuxeo.ecm.core.query.sql.NXQL;
035import org.nuxeo.ecm.platform.query.api.PageProvider;
036import org.nuxeo.ecm.platform.query.api.PageProviderDefinition;
037import org.nuxeo.ecm.platform.query.api.PageProviderService;
038
039import java.util.Collections;
040import java.util.Map;
041
042/**
043 * @since 6.0 Document query operation to perform queries on the repository.
044 */
045@Operation(id = DocumentPaginatedQuery.ID, category = Constants.CAT_FETCH, label = "Query", description = "Perform a query on the repository. "
046        + "The document list returned will become the input for the next operation."
047        + "If no provider name is given, a query returning all the documents that the user has access to will be executed.",
048        since = "6.0", addToStudio = true, aliases = { "Document.Query" })
049public class DocumentPaginatedQuery {
050
051    public static final String ID = "Repository.Query";
052
053    public static final String DESC = "DESC";
054
055    public static final String ASC = "ASC";
056
057    @Context
058    protected CoreSession session;
059
060    @Param(name = "query", required = false, description = "The query to perform.")
061    protected String query;
062
063    @Param(name = "language", required = false, description = "The query language.",
064            widget = Constants.W_OPTION, values = { NXQL.NXQL })
065    protected String lang = NXQL.NXQL;
066
067    @Param(name = "currentPageIndex", alias = "page", required = false, description = "Target listing page.")
068    protected Integer currentPageIndex;
069
070    @Param(name = "pageSize", required = false, description = "Entries number per page.")
071    protected Integer pageSize;
072
073    @Param(name = "queryParams", alias = "searchTerm", required = false, description = "Ordered query parameters.")
074    protected StringList strParameters;
075
076    @Param(name = "sortBy", required = false, description = "Sort by properties (separated by comma)")
077    protected StringList sortBy;
078
079    @Param(name = "sortOrder", required = false, description = "Sort order, ASC or DESC",
080            widget = Constants.W_OPTION, values = { ASC, DESC })
081    protected StringList sortOrder;
082
083    @Param(name = PageProviderService.NAMED_PARAMETERS, required = false,
084            description = "Named parameters to pass to the page provider to fill in query variables.")
085    protected Properties namedParameters;
086
087    /**
088     * @since 10.3
089     */
090    @Param(name = "maxResults", required = false)
091    protected Integer maxResults;
092
093    /**
094     * @since 11,1
095     */
096    @Param(name = "quotePatternParameters", required = false)
097    protected Boolean quotePatternParameters = true;
098
099    /**
100     * @since 11.1
101     */
102    @Param(name = "escapePatternParameters", required = false)
103    protected Boolean escapePatternParameters = true;
104
105    @SuppressWarnings("unchecked")
106    @OperationMethod
107    public DocumentModelList run() throws OperationException {
108        if (query == null) {
109            // provide a default query
110            query = "SELECT * from Document";
111        }
112        Map<String, String> properties = null;
113        if (maxResults != null) {
114            properties = Collections.singletonMap("maxResults", maxResults.toString());
115        }
116        PageProviderDefinition def = PageProviderHelper.getQueryPageProviderDefinition(query, properties,
117                escapePatternParameters, quotePatternParameters);
118
119        Long targetPage = currentPageIndex != null ? currentPageIndex.longValue() : null;
120        Long targetPageSize = pageSize != null ? pageSize.longValue() : null;
121
122        PageProvider<DocumentModel> pp = (PageProvider<DocumentModel>) PageProviderHelper.getPageProvider(session, def,
123                namedParameters, sortBy, sortOrder, targetPageSize, targetPage,
124                strParameters != null ? strParameters.toArray(new String[0]) : null);
125
126        PaginableDocumentModelListImpl res = new PaginableDocumentModelListImpl(pp);
127        if (res.hasError()) {
128            throw new OperationException(res.getErrorMessage());
129        }
130        return res;
131    }
132}