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 * <a href="mailto:grenard@nuxeo.com">Guillaume</a> 016 */ 017package org.nuxeo.ecm.platform.ui.select2.common; 018 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.List; 022 023import net.sf.json.JSONArray; 024import net.sf.json.JSONObject; 025 026import org.apache.commons.lang.StringUtils; 027import org.apache.commons.logging.Log; 028import org.apache.commons.logging.LogFactory; 029import org.nuxeo.ecm.core.schema.types.Schema; 030import org.nuxeo.ecm.platform.usermanager.UserConfig; 031import org.nuxeo.runtime.api.Framework; 032import org.nuxeo.runtime.services.config.ConfigurationService; 033 034/** 035 * Group fields and methods used at initialization and runtime for select2 feature. 036 * 037 * @since 5.7.3 038 */ 039public class Select2Common { 040 041 private static final Log log = LogFactory.getLog(Select2Common.class); 042 043 private static final String FORCE_DISPLAY_EMAIL_IN_SUGGESTION = "nuxeo.ui.displayEmailInUserSuggestion"; 044 045 public static final String LANG_TOKEN = "{lang}"; 046 047 public static final String DEFAULT_LANG = "en"; 048 049 public static final String ID = "id"; 050 051 public static final String LABEL = "displayLabel"; 052 053 public static final String DIRECTORY_DEFAULT_LABEL_COL_NAME = "label"; 054 055 public static final String PARENT_FIELD_ID = "parent"; 056 057 public static final String PLACEHOLDER = "placeholder"; 058 059 public static final String COMPUTED_ID = "computedId"; 060 061 public static final String DEFAULT_KEY_SEPARATOR = "/"; 062 063 public static final String OBSOLETE_FIELD_ID = "obsolete"; 064 065 public static final List<String> SELECT2_USER_WIDGET_TYPE_LIST = new ArrayList<String>(Arrays.asList( 066 "singleUserSuggestion", "multipleUsersSuggestion")); 067 068 public static final List<String> SELECT2_DOC_WIDGET_TYPE_LIST = new ArrayList<String>(Arrays.asList( 069 "singleDocumentSuggestion", "multipleDocumentsSuggestion")); 070 071 public static final String USER_TYPE = "USER_TYPE"; 072 073 public static final String GROUP_TYPE = "GROUP_TYPE"; 074 075 public static final String TYPE_KEY_NAME = "type"; 076 077 public static final String PREFIXED_ID_KEY_NAME = "prefixed_id"; 078 079 public static final String SUGGESTION_FORMATTER = "suggestionFormatter"; 080 081 public static final String SELECTION_FORMATTER = "selectionFormatter"; 082 083 public static final String USER_DEFAULT_SUGGESTION_FORMATTER = "userEntryDefaultFormatter"; 084 085 public static final String DOC_DEFAULT_SUGGESTION_FORMATTER = "docEntryDefaultFormatter"; 086 087 public static final String WARN_MESSAGE_LABEL = "warn_message"; 088 089 public static final List<String> SELECT2_DIR_WIDGET_TYPE_LIST = new ArrayList<String>(Arrays.asList( 090 "suggestOneDirectory", "suggestManyDirectory")); 091 092 public static final List<String> SELECT2_DEFAULT_DOCUMENT_SCHEMAS = new ArrayList<String>(Arrays.asList( 093 "dublincore", "common")); 094 095 public static final String DIR_DEFAULT_SUGGESTION_FORMATTER = "dirEntryDefaultFormatter"; 096 097 public static final String READ_ONLY_PARAM = "readonly"; 098 099 public static final String RERENDER_JS_FUNCTION_NAME = "reRenderFunctionName"; 100 101 public static final String AJAX_RERENDER = "ajaxReRender"; 102 103 public static final String USER_DEFAULT_SELECTION_FORMATTER = "userSelectionDefaultFormatter"; 104 105 public static final String DOC_DEFAULT_SELECTION_FORMATTER = "docSelectionDefaultFormatter"; 106 107 public static final String DIR_DEFAULT_SELECTION_FORMATTER = "dirSelectionDefaultFormatter"; 108 109 public static final String WIDTH = "width"; 110 111 public static final String DEFAULT_WIDTH = "300"; 112 113 public static final String MIN_CHARS = "minChars"; 114 115 public static final int DEFAULT_MIN_CHARS = 3; 116 117 public static final String TITLE = "title"; 118 119 public static final String DISPLAY_ICON = "displayIcon"; 120 121 public static final String OPERATION_ID = "operationId"; 122 123 public static final String DIRECTORY_ORDER_FIELD_NAME = "ordering"; 124 125 public static final String ABSOLUTE_LABEL = "absoluteLabel"; 126 127 private static Boolean forceDisplayEmailInSuggestion = null; 128 129 public static final String ICON = "icon"; 130 131 private static boolean isForceDisplayEmailInSuggestion() { 132 if (forceDisplayEmailInSuggestion == null) { 133 ConfigurationService cs = Framework.getService(ConfigurationService.class); 134 forceDisplayEmailInSuggestion = cs.isBooleanPropertyTrue(FORCE_DISPLAY_EMAIL_IN_SUGGESTION); 135 } 136 return forceDisplayEmailInSuggestion; 137 } 138 139 /** 140 * @since 5.9.3 141 */ 142 public static String[] getDefaultSchemas() { 143 return getSchemas(null); 144 } 145 146 /** 147 * Compute the field name of the directory that holds the value that we want to display. 148 * 149 * @param schema the directory schema 150 * @param dbl10n are translations carried by directory fields 151 * @param labelFieldName the name or pattern of the fields that held values 152 * @param lang the current language 153 * @throws IllegalArgumentException when cannot compute label field name 154 * @return the final field name where we pick up the value 155 * @since 5.7.3 156 */ 157 public static String getLabelFieldName(final Schema schema, boolean dbl10n, String labelFieldName, final String lang) { 158 if (labelFieldName == null || labelFieldName.isEmpty()) { 159 // No labelFieldName provided, we assume it is 'label' 160 labelFieldName = DIRECTORY_DEFAULT_LABEL_COL_NAME; 161 } 162 if (dbl10n) { 163 int i = labelFieldName.indexOf(LANG_TOKEN); 164 if (i >= 0) { 165 // a pattern is provided, let's compute the field name 166 // according 167 // to the current lang 168 StringBuffer buf = new StringBuffer(); 169 buf.append(labelFieldName.substring(0, i)); 170 buf.append(lang); 171 buf.append(labelFieldName.substring(i + LANG_TOKEN.length())); 172 String result = buf.toString(); 173 if (schema.getField(result) != null) { 174 return result; 175 } else { 176 // there is no field for the current lang, let's pick 177 // english by default 178 buf = new StringBuffer(); 179 buf.append(labelFieldName.substring(0, i)); 180 buf.append(DEFAULT_LANG); 181 buf.append(labelFieldName.substring(i + LANG_TOKEN.length())); 182 return buf.toString(); 183 } 184 } else { 185 // No pattern 186 String result = labelFieldName + "_" + lang; 187 if (schema.getField(result) != null) { 188 // we assume that fields are named like 'xxx_en', 189 // 'xxx_fr', etc. 190 return result; 191 } 192 193 log.warn(String.format( 194 "Unable to find field %s in directory schema %s. Trying to fallback on default one.", 195 labelFieldName, schema.getName())); 196 197 result = DIRECTORY_DEFAULT_LABEL_COL_NAME + "_" + DEFAULT_LANG; 198 if (schema.getField(result) != null) { 199 // no available locale, fallback to english by default 200 return result; 201 } 202 result = DIRECTORY_DEFAULT_LABEL_COL_NAME; 203 if (schema.getField(result) != null) { 204 // no available default locale, fallback to label 205 return result; 206 } 207 208 if (schema.getField(labelFieldName) != null) { 209 // let's pretend this is not dbl10n 210 return labelFieldName; 211 } 212 213 throw new IllegalArgumentException(String.format("Unable to find field %s in directory schema %s", 214 labelFieldName, schema.getName())); 215 } 216 } else { 217 if (schema.getField(labelFieldName) != null) { 218 return labelFieldName; 219 } else { 220 throw new IllegalArgumentException(String.format("Unable to find field %s in directory schema %s", 221 labelFieldName, schema.getName())); 222 } 223 } 224 } 225 226 /** 227 * Returns an array containing the given schema names plus the default ones if not included 228 * 229 * @param schemaNames 230 * @since 5.8 231 */ 232 public static String[] getSchemas(final String schemaNames) { 233 List<String> result = new ArrayList<String>(); 234 result.addAll(Select2Common.SELECT2_DEFAULT_DOCUMENT_SCHEMAS); 235 String[] temp = null; 236 if (schemaNames != null && !schemaNames.isEmpty()) { 237 temp = schemaNames.split(","); 238 } 239 if (temp != null) { 240 for (String s : temp) { 241 result.add(s); 242 } 243 } 244 return result.toArray(new String[result.size()]); 245 } 246 247 public static void computeUserLabel(final JSONObject obj, final String firstLabelField, 248 final String secondLabelField, final String thirdLabelField, final boolean hideFirstLabel, 249 final boolean hideSecondLabel, final boolean hideThirdLabel, boolean displayEmailInSuggestion, 250 final String userId) { 251 String result = ""; 252 if (obj != null) { 253 254 if (StringUtils.isNotBlank(firstLabelField) && !hideFirstLabel) { 255 // If firtLabelField given and first label not hidden 256 final String firstLabel = obj.optString(firstLabelField); 257 result += StringUtils.isNotBlank(firstLabel) ? firstLabel : ""; 258 } else if (!hideFirstLabel) { 259 // Else we use firstname 260 final String firstname = obj.optString(UserConfig.FIRSTNAME_COLUMN); 261 result += StringUtils.isNotBlank(firstname) ? firstname : ""; 262 } 263 264 if (StringUtils.isNotBlank(secondLabelField) && !hideSecondLabel) { 265 // If secondLabelField given and second label not hidden 266 final String secondLabel = obj.optString(firstLabelField); 267 if (StringUtils.isNotBlank(secondLabel)) { 268 if (StringUtils.isNotBlank(result)) { 269 result += " "; 270 } 271 result += secondLabel; 272 } 273 } else if (!hideSecondLabel) { 274 // Else we use lastname 275 final String lastname = obj.optString(UserConfig.LASTNAME_COLUMN); 276 if (StringUtils.isNotBlank(lastname)) { 277 if (StringUtils.isNotBlank(result)) { 278 result += " "; 279 } 280 result += lastname; 281 } 282 } 283 if (StringUtils.isBlank(result)) { 284 // At this point, if returned label is empty, we use user id 285 result += StringUtils.isNotBlank(userId) ? userId : ""; 286 } 287 288 if (isForceDisplayEmailInSuggestion() || (displayEmailInSuggestion && !hideThirdLabel)) { 289 if (StringUtils.isNotBlank(thirdLabelField)) { 290 final String thirdLabel = obj.optString(thirdLabelField); 291 if (StringUtils.isNotBlank(thirdLabel)) { 292 if (StringUtils.isNotBlank(result)) { 293 result += " "; 294 } 295 result += thirdLabel; 296 } 297 } else { 298 // Else we use email 299 String email = obj.optString(UserConfig.EMAIL_COLUMN); 300 if (StringUtils.isNotBlank(email)) { 301 if (StringUtils.isNotBlank(result)) { 302 result += " "; 303 } 304 result += email; 305 } 306 } 307 } 308 309 obj.put(LABEL, result); 310 } 311 } 312 313 public static void computeGroupLabel(final JSONObject obj, final String groupId, final String groupLabelField, 314 final boolean hideFirstLabel) { 315 String label = null; 316 if (hideFirstLabel) { 317 label = groupId; 318 } else { 319 String groupLabelValue = obj.optString(groupLabelField); 320 if (StringUtils.isNotBlank(groupLabelValue)) { 321 label = groupLabelValue; 322 } else { 323 label = groupId; 324 } 325 } 326 obj.put(LABEL, label); 327 } 328 329 public static void computeUserGroupIcon(final JSONObject obj, final boolean hideIcon) { 330 if (obj != null) { 331 if (!hideIcon) { 332 String userGroupType = obj.optString(TYPE_KEY_NAME); 333 obj.element(DISPLAY_ICON, StringUtils.isNotBlank(userGroupType) 334 && (userGroupType.equals(USER_TYPE) || userGroupType.equals(GROUP_TYPE))); 335 } 336 } 337 } 338 339 /** 340 * @since 6.0 341 */ 342 public static String resolveDefaultEntries(final List<String> list) { 343 if (list == null || list.isEmpty()) { 344 return "[]"; 345 } else { 346 JSONArray result = new JSONArray(); 347 for (String l : list) { 348 JSONObject obj = new JSONObject(); 349 obj.element(Select2Common.ID, l); 350 obj.element(Select2Common.LABEL, l); 351 result.add(obj); 352 } 353 return result.toString(); 354 } 355 } 356 357}