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     * Limit the number of results displayed to the user to avoid performance problems
073     */
074    public static int LIMIT_RESULTS = 15;
075
076    @OperationMethod
077    public DocumentModelList run() {
078        Locale locale = lang != null && !lang.isEmpty() ? new Locale(lang) : Locale.ENGLISH;
079        if (value != null && !"".equals(value)) {
080            return getAllUserOpenTask(session, locale, value, false);
081        }
082        return getAllUserOpenTask(session, locale, searchTerm, true);
083    }
084
085    /**
086     * Returns all user tasks having their translated name matching ( partially or fully ) the given label.
087     */
088    protected DocumentModelList getAllUserOpenTask(CoreSession session, Locale locale, String searchTerm,
089            boolean partialMatch) {
090        DocumentModelList list = new DocumentModelListImpl();
091        String query = "Select * from TaskDoc where ecm:mixinType IN ('RoutingTask') AND ecm:isCheckedInVersion = 0 AND ecm:currentLifeCycleState = 'opened'";
092        Map<String, DocumentModel> results = new HashMap<String, DocumentModel>();
093        DocumentModelList docs = session.query(query);
094        int i = 0;
095        for (DocumentModel doc : docs) {
096            String taskName = (String) doc.getPropertyValue("nt:name");
097            String taskLabel = getI18nLabel(taskName, locale);
098            if (partialMatch) {
099                // a translaedLabel == "" corresponds to the list of all
100                // tasks
101                if (searchTerm == null || "".equals(searchTerm)) {
102                    doc.setPropertyValue("dc:title",
103                            "[" + getWorkflowTranslatedTitle(doc, locale) + "]" + " " + taskLabel);
104                    results.put(taskName, doc);
105                    i++;
106                } else {
107                    // add doc to result set only if the translated label
108                    // starts with the 'searchTerm'
109                    if (taskLabel.startsWith(searchTerm)) {
110                        doc.setPropertyValue("dc:title",
111                                "[" + getWorkflowTranslatedTitle(doc, locale) + "]" + " " + taskLabel);
112                        results.put(taskName, doc);
113                        i++;
114                    }
115                }
116            }
117            if (!partialMatch && searchTerm.equals(taskName)) {
118                doc.setPropertyValue("dc:title", "[" + getWorkflowTranslatedTitle(doc, locale) + "]" + " " + taskLabel);
119                results.put(taskName, doc);
120                i++;
121                break;
122            }
123            if (i > LIMIT_RESULTS) {
124                break;
125            }
126        }
127        list.addAll(results.values());
128        return list;
129    }
130
131    protected String getI18nLabel(String label, Locale locale) {
132        if (label == null) {
133            label = "";
134        }
135        return I18NUtils.getMessageString("messages", label, null, locale);
136    }
137
138    protected String getWorkflowTranslatedTitle(DocumentModel taskDoc, Locale locale) throws PropertyException {
139        String workflowId = (String) taskDoc.getPropertyValue("nt:processId");
140        DocumentModel workflowDoc = session.getDocument(new IdRef(workflowId));
141        return getI18nLabel(workflowDoc.getTitle(), locale);
142    }
143}