001/*
002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     guillaume
016 */
017package org.nuxeo.ecm.platform.routing.core.api.operation;
018
019import java.util.HashMap;
020import java.util.Locale;
021import java.util.Map;
022
023import org.nuxeo.common.utils.i18n.I18NUtils;
024import org.nuxeo.ecm.automation.OperationContext;
025import org.nuxeo.ecm.automation.core.Constants;
026import org.nuxeo.ecm.automation.core.annotations.Context;
027import org.nuxeo.ecm.automation.core.annotations.Operation;
028import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
029import org.nuxeo.ecm.automation.core.annotations.Param;
030import org.nuxeo.ecm.core.api.CoreSession;
031import org.nuxeo.ecm.core.api.DocumentModel;
032import org.nuxeo.ecm.core.api.DocumentModelList;
033import org.nuxeo.ecm.core.api.IdRef;
034import org.nuxeo.ecm.core.api.PropertyException;
035import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
036
037/**
038 * Returns a list of current user open tasks where their translated name matches (partially or fully) the 'searchTerm'
039 * parameter. This operation is invoked from a select2widget and the number of returned results is limited to 15.
040 *
041 * @since 5.8
042 */
043@Operation(id = GetTaskNamesOperation.ID, category = Constants.CAT_WORKFLOW, label = "Get Task Translated Names", description = "Returns a "
044        + "list of current user open tasks where their translated name matches "
045        + "(partially or fully ) the 'searchTerm' parameter. This operation is "
046        + "invoked from a select2widget and the number of returned results is " + "limited to 15.", addToStudio = false)
047public class GetTaskNamesOperation {
048
049    public static final String ID = "Context.GetTaskNames";
050
051    @Context
052    protected OperationContext ctx;
053
054    @Context
055    protected CoreSession session;
056
057    @Param(name = "lang", required = false)
058    protected String lang;
059
060    @Param(name = "searchTerm", required = false)
061    protected String searchTerm;
062
063    @Param(name = "value", required = false)
064    protected String value;
065
066    @Param(name = "xpath", required = false)
067    protected String xpath;
068
069    /**
070     * Limit the number of results displayed to the user to avoid performance problems
071     */
072    public static int LIMIT_RESULTS = 15;
073
074    @OperationMethod
075    public DocumentModelList run() {
076        Locale locale = lang != null && !lang.isEmpty() ? new Locale(lang) : Locale.ENGLISH;
077        if (value != null && !"".equals(value)) {
078            return getAllUserOpenTask(session, locale, value, false);
079        }
080        return getAllUserOpenTask(session, locale, searchTerm, true);
081    }
082
083    /**
084     * Returns all user tasks having their translated name matching ( partially or fully ) the given label.
085     */
086    protected DocumentModelList getAllUserOpenTask(CoreSession session, Locale locale, String searchTerm,
087            boolean partialMatch) {
088        DocumentModelList list = new DocumentModelListImpl();
089        String query = "Select * from TaskDoc where ecm:mixinType IN ('RoutingTask') AND ecm:isCheckedInVersion = 0 AND ecm:currentLifeCycleState = 'opened'";
090        Map<String, DocumentModel> results = new HashMap<String, DocumentModel>();
091        DocumentModelList docs = session.query(query);
092        int i = 0;
093        for (DocumentModel doc : docs) {
094            String taskName = (String) doc.getPropertyValue("nt:name");
095            String taskLabel = getI18nLabel(taskName, locale);
096            if (partialMatch) {
097                // a translaedLabel == "" corresponds to the list of all
098                // tasks
099                if (searchTerm == null || "".equals(searchTerm)) {
100                    doc.setPropertyValue("dc:title",
101                            "[" + getWorkflowTranslatedTitle(doc, locale) + "]" + " " + taskLabel);
102                    results.put(taskName, doc);
103                    i++;
104                } else {
105                    // add doc to result set only if the translated label
106                    // starts with the 'searchTerm'
107                    if (taskLabel.startsWith(searchTerm)) {
108                        doc.setPropertyValue("dc:title",
109                                "[" + getWorkflowTranslatedTitle(doc, locale) + "]" + " " + taskLabel);
110                        results.put(taskName, doc);
111                        i++;
112                    }
113                }
114            }
115            if (!partialMatch && searchTerm.equals(taskName)) {
116                doc.setPropertyValue("dc:title", "[" + getWorkflowTranslatedTitle(doc, locale) + "]" + " " + taskLabel);
117                results.put(taskName, doc);
118                i++;
119                break;
120            }
121            if (i > LIMIT_RESULTS) {
122                break;
123            }
124        }
125        list.addAll(results.values());
126        return list;
127    }
128
129    protected String getI18nLabel(String label, Locale locale) {
130        if (label == null) {
131            label = "";
132        }
133        return I18NUtils.getMessageString("messages", label, null, locale);
134    }
135
136    protected String getWorkflowTranslatedTitle(DocumentModel taskDoc, Locale locale) throws PropertyException {
137        String workflowId = (String) taskDoc.getPropertyValue("nt:processId");
138        DocumentModel workflowDoc = session.getDocument(new IdRef(workflowId));
139        return getI18nLabel(workflowDoc.getTitle(), locale);
140    }
141}