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}