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