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