001/*
002 * (C) Copyright 2018 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 *     guillaume
018 *     Nuno Cunha (ncunha@nuxeo.com)
019 */
020package org.nuxeo.ecm.platform.routing.core.api.operation;
021
022import java.util.HashMap;
023import java.util.Locale;
024import java.util.Map;
025
026import org.nuxeo.common.utils.i18n.I18NUtils;
027import org.nuxeo.ecm.automation.OperationContext;
028import org.nuxeo.ecm.automation.core.Constants;
029import org.nuxeo.ecm.automation.core.annotations.Context;
030import org.nuxeo.ecm.automation.core.annotations.Operation;
031import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
032import org.nuxeo.ecm.automation.core.annotations.Param;
033import org.nuxeo.ecm.core.api.CoreSession;
034import org.nuxeo.ecm.core.api.DocumentModel;
035import org.nuxeo.ecm.core.api.DocumentModelList;
036import org.nuxeo.ecm.core.api.IdRef;
037import org.nuxeo.ecm.core.api.PropertyException;
038import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
039
040/**
041 * Returns a list of current user open tasks where their translated name matches (partially or fully) the 'searchTerm'
042 * parameter. This operation is invoked from a select2widget and the number of returned results is limited to 15.
043 *
044 * @since 5.8
045 */
046@Operation(id = GetTaskNamesOperation.ID, category = Constants.CAT_WORKFLOW, label = "Get Task Translated Names", description = "Returns a "
047        + "list of current user open tasks where their translated name matches "
048        + "(partially or fully ) the 'searchTerm' parameter. This operation is "
049        + "invoked from a select2widget and the number of returned results is " + "limited to 15.", addToStudio = false)
050public class GetTaskNamesOperation {
051
052    public static final String ID = "Context.GetTaskNames";
053
054    @Context
055    protected OperationContext ctx;
056
057    @Context
058    protected CoreSession session;
059
060    @Param(name = "lang", required = false)
061    protected String lang;
062
063    @Param(name = "searchTerm", required = false)
064    protected String searchTerm;
065
066    @Param(name = "value", required = false)
067    protected String value;
068
069    @Param(name = "xpath", required = false)
070    protected String xpath;
071
072    /**
073     * @since 8.4
074     */
075    @Param(name = "limit", required = false)
076    protected int limit = -1;
077
078    @OperationMethod
079    public DocumentModelList run() {
080        Locale locale = lang != null && !lang.isEmpty() ? new Locale(lang) : Locale.ENGLISH;
081        if (value != null && !"".equals(value)) {
082            return getAllUserOpenTask(session, locale, value, false);
083        }
084        return getAllUserOpenTask(session, locale, searchTerm, true);
085    }
086
087    /**
088     * Returns all user tasks having their translated name matching ( partially or fully ) the given label.
089     */
090    protected DocumentModelList getAllUserOpenTask(CoreSession session, Locale locale, String searchTerm,
091            boolean partialMatch) {
092        DocumentModelList list = new DocumentModelListImpl();
093        String query = "Select * from Document where ecm:mixinType IN ('RoutingTask') AND ecm:isVersion = 0 AND ecm:currentLifeCycleState = 'opened'";
094        Map<String, DocumentModel> results = new HashMap<>();
095        DocumentModelList docs = session.query(query);
096        int i = 0;
097        for (DocumentModel doc : docs) {
098            String taskName = (String) doc.getPropertyValue("nt:name");
099            String taskLabel = getI18nLabel(taskName, locale);
100            if (partialMatch) {
101                // a translatedLabel == "" corresponds to the list of all
102                // tasks
103                if (searchTerm == null || "".equals(searchTerm)) {
104                    doc.setPropertyValue("dc:title",
105                            "[" + getWorkflowTranslatedTitle(doc, locale) + "]" + " " + taskLabel);
106                    results.put(taskName, doc);
107                    i++;
108                } else {
109                    // add doc to result set only if the translated label
110                    // starts with the 'searchTerm'
111                    if (taskLabel.startsWith(searchTerm)) {
112                        doc.setPropertyValue("dc:title",
113                                "[" + getWorkflowTranslatedTitle(doc, locale) + "]" + " " + taskLabel);
114                        results.put(taskName, doc);
115                        i++;
116                    }
117                }
118            }
119            if (!partialMatch && searchTerm.equals(taskName)) {
120                doc.setPropertyValue("dc:title", "[" + getWorkflowTranslatedTitle(doc, locale) + "]" + " " + taskLabel);
121                results.put(taskName, doc);
122                break;
123            }
124            if (limit > 0 && i > limit) {
125                break;
126            }
127        }
128        list.addAll(results.values());
129        return list;
130    }
131
132    protected String getI18nLabel(String label, Locale locale) {
133        if (label == null) {
134            label = "";
135        }
136        return I18NUtils.getMessageString("messages", label, null, locale);
137    }
138
139    protected String getWorkflowTranslatedTitle(DocumentModel taskDoc, Locale locale) throws PropertyException {
140        String workflowId = (String) taskDoc.getPropertyValue("nt:processId");
141        DocumentModel workflowDoc = session.getDocument(new IdRef(workflowId));
142        return getI18nLabel(workflowDoc.getTitle(), locale);
143    }
144}