001/* 002 * (C) Copyright 2006-2007 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 * Nuxeo - initial API and implementation 018 * 019 * $Id: DirectoryEntryOutputComponent.java 23036 2007-07-27 11:34:11Z btatar $ 020 */ 021 022package org.nuxeo.ecm.platform.ui.web.directory; 023 024import java.io.Serializable; 025import java.util.ArrayList; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Locale; 029import java.util.Map; 030 031import javax.faces.component.UIOutput; 032import javax.faces.context.FacesContext; 033import javax.faces.el.ValueBinding; 034 035import org.apache.commons.lang3.StringUtils; 036import org.apache.commons.logging.Log; 037import org.apache.commons.logging.LogFactory; 038import org.nuxeo.common.utils.i18n.I18NUtils; 039 040/** 041 * Component to display a chained directory entry. 042 * 043 * @author <a href="mailto:[email protected]">George Lefter</a> 044 */ 045public class ChainSelectOutputComponent extends UIOutput { 046 047 public static final String COMPONENT_TYPE = "nxdirectory.ChainSelectOutput"; 048 049 public static final String COMPONENT_FAMILY = "nxdirectory.ChainSelectOutput"; 050 051 @SuppressWarnings("unused") 052 private static final Log log = LogFactory.getLog(ChainSelect.class); 053 054 private static final String DISPLAY_ID_AND_LABEL_SEPARATOR = " "; 055 056 private static final String DEFAULT_ENTRY_SEPARATOR = ", "; 057 058 protected Boolean displayIdAndLabel; 059 060 protected Boolean localize; 061 062 protected String display; 063 064 protected String directoryNameList; 065 066 protected Boolean displayObsoleteEntries; 067 068 protected String keySeparator; 069 070 protected String displayKeySeparator; 071 072 protected Boolean qualifiedParentKeys; 073 074 protected Boolean handleMultipleValues = false; 075 076 private String entrySeparator; 077 078 private String cssStyle; 079 080 private String cssStyleClass; 081 082 public ChainSelectOutputComponent() { 083 setRendererType(COMPONENT_TYPE); 084 } 085 086 @Override 087 public String getFamily() { 088 return COMPONENT_FAMILY; 089 } 090 091 public String getKeySeparator() { 092 String ret = null; 093 ValueBinding vb = getValueBinding("keySeparator"); 094 if (vb != null) { 095 ret = (String) vb.getValue(getFacesContext()); 096 } else { 097 ret = keySeparator; 098 } 099 if (ret == null) { 100 ret = ChainSelect.DEFAULT_KEY_SEPARATOR; 101 } 102 return ret; 103 } 104 105 public void setDisplayKeySeparator(String keySeparator) { 106 displayKeySeparator = keySeparator; 107 } 108 109 public String getDisplayKeySeparator() { 110 String ret = null; 111 ValueBinding vb = getValueBinding("displayKeySeparator"); 112 if (vb != null) { 113 ret = (String) vb.getValue(getFacesContext()); 114 } else { 115 ret = displayKeySeparator; 116 } 117 if (ret == null) { 118 ret = getKeySeparator(); 119 } 120 return ret; 121 } 122 123 public void setKeySeparator(String keySeparator) { 124 this.keySeparator = keySeparator; 125 } 126 127 public boolean getQualifiedParentKeys() { 128 Boolean ret = null; 129 ValueBinding vb = getValueBinding("qualifiedParentKeys"); 130 if (vb != null) { 131 ret = (Boolean) vb.getValue(getFacesContext()); 132 } else { 133 ret = qualifiedParentKeys; 134 } 135 return Boolean.TRUE.equals(ret); 136 } 137 138 public boolean getHandleMultipleValues() { 139 Boolean ret = null; 140 ValueBinding vb = getValueBinding("handleMultipleValues"); 141 if (vb != null) { 142 ret = (Boolean) vb.getValue(getFacesContext()); 143 } else { 144 ret = handleMultipleValues; 145 } 146 return Boolean.TRUE.equals(ret); 147 } 148 149 public void setHandleMultipleValues(boolean handleMultipleValues) { 150 this.handleMultipleValues = handleMultipleValues; 151 } 152 153 public void setQualifiedParentKeys(boolean qualifiedParentKeys) { 154 this.qualifiedParentKeys = qualifiedParentKeys; 155 } 156 157 /** 158 * @deprecated use display=id|label|idAndLabel instead 159 */ 160 @Deprecated 161 public boolean getDisplayIdAndLabel() { 162 Boolean ret; 163 ValueBinding vb = getValueBinding("displayIdAndLabel"); 164 if (vb != null) { 165 ret = (Boolean) vb.getValue(getFacesContext()); 166 } else { 167 ret = displayIdAndLabel; 168 } 169 return Boolean.TRUE.equals(ret); 170 } 171 172 public void setDisplayIdAndLabel(boolean displayIdAndLabel) { 173 this.displayIdAndLabel = displayIdAndLabel; 174 } 175 176 public boolean getLocalize() { 177 return Boolean.TRUE.equals(localize); 178 } 179 180 public void setLocalize(boolean localize) { 181 this.localize = localize; 182 } 183 184 /** 185 * Hide legacy "displayIdAndLabel" property. Use "display" if set; else if "displayIdAndLabel" is true, return 186 * "idAndLabel", else default to "label". 187 * 188 * @return whether to display the id, the label or both 189 */ 190 public String getDisplay() { 191 String ret; 192 ValueBinding vb = getValueBinding("display"); 193 if (vb != null) { 194 ret = (String) vb.getValue(getFacesContext()); 195 } else { 196 ret = display; 197 } 198 199 if (ret == null) { 200 boolean displayIdAndLabel = getDisplayIdAndLabel(); 201 ret = displayIdAndLabel ? "idAndLabel" : "label"; 202 } 203 204 return ret; 205 } 206 207 public void setDisplay(String display) { 208 this.display = display; 209 } 210 211 @Override 212 public Object saveState(FacesContext context) { 213 Object[] values = new Object[12]; 214 values[0] = super.saveState(context); 215 values[1] = displayIdAndLabel; 216 values[2] = localize; 217 values[3] = display; 218 values[4] = displayObsoleteEntries; 219 values[5] = directoryNameList; 220 values[6] = qualifiedParentKeys; 221 values[7] = keySeparator; 222 values[8] = cssStyle; 223 values[9] = cssStyleClass; 224 values[10] = entrySeparator; 225 values[11] = handleMultipleValues; 226 return values; 227 } 228 229 @Override 230 public void restoreState(FacesContext context, Object state) { 231 Object[] values = (Object[]) state; 232 super.restoreState(context, values[0]); 233 displayIdAndLabel = (Boolean) values[1]; 234 localize = (Boolean) values[2]; 235 display = (String) values[3]; 236 displayObsoleteEntries = (Boolean) values[4]; 237 directoryNameList = (String) values[5]; 238 qualifiedParentKeys = (Boolean) values[6]; 239 keySeparator = (String) values[7]; 240 cssStyle = (String) values[8]; 241 cssStyleClass = (String) values[9]; 242 entrySeparator = (String) values[10]; 243 handleMultipleValues = (Boolean) values[11]; 244 } 245 246 public boolean getDisplayObsoleteEntries() { 247 return Boolean.TRUE.equals(displayObsoleteEntries); 248 } 249 250 /** 251 * Transform a comma-separated list of keys into a selection. The list can be separated by the <b>keySeparator</b> 252 * string 253 * 254 * @param keyEnum the comma-separated list of keys 255 * @return 256 */ 257 public Selection createSelection(String keyEnum) { 258 String keySeparator = getKeySeparator(); 259 String[] columns = StringUtils.split(keyEnum, keySeparator); 260 261 List<String> keyList = new ArrayList<String>(); 262 List<DirectorySelectItem> itemList = new ArrayList<DirectorySelectItem>(); 263 String directoryNameList = getDirectoryNameList(); 264 String[] directoryNames = StringUtils.split(directoryNameList, ","); 265 boolean qualifiedParentKeys = getQualifiedParentKeys(); 266 boolean displayObsoleteEntries = getDisplayObsoleteEntries(); 267 String display = getDisplay(); 268 269 for (int i = 0; i < directoryNames.length; i++) { 270 directoryNames[i] = directoryNames[i].trim(); 271 } 272 273 for (int i = 0; i < columns.length; i++) { 274 String id = columns[i]; 275 276 String directoryName = directoryNames[i]; 277 278 Map<String, Serializable> filter = new HashMap<String, Serializable>(); 279 filter.put("id", id); 280 281 if (i == 0) { 282 if (DirectoryHelper.instance().hasParentColumn(directoryName)) { 283 // explicitely filter on NULL parent in a xvocabulary 284 filter.put("parent", null); 285 } 286 } else { 287 String parentId; 288 if (qualifiedParentKeys) { 289 parentId = StringUtils.join(keyList.iterator(), keySeparator); 290 } else { 291 parentId = columns[i - 1]; 292 } 293 filter.put("parent", parentId); 294 } 295 296 keyList.add(id); 297 298 if (!displayObsoleteEntries) { 299 filter.put("obsolete", 0); 300 } 301 DirectorySelectItem item = DirectoryHelper.instance().getSelectItem(directoryName, filter); 302 if (item == null) { 303 item = new DirectorySelectItem(id, id); 304 } 305 String itemId = (String) item.getValue(); 306 String label = item.getLabel(); 307 if (getLocalize()) { 308 label = translate(getFacesContext(), label); 309 } 310 if ("id".equals(display)) { 311 label = id; 312 } else if ("idAndLabel".equals(display)) { 313 label = itemId + DISPLAY_ID_AND_LABEL_SEPARATOR + label; 314 } 315 item.setLabel(label); 316 itemList.add(item); 317 } 318 return new Selection(itemList.toArray(new DirectorySelectItem[columns.length])); 319 } 320 321 protected static String translate(FacesContext context, String label) { 322 String bundleName = context.getApplication().getMessageBundle(); 323 Locale locale = context.getViewRoot().getLocale(); 324 label = I18NUtils.getMessageString(bundleName, label, null, locale); 325 return label; 326 } 327 328 public String getEntrySeparator() { 329 String ret = null; 330 ValueBinding vb = getValueBinding("entrySeparator"); 331 if (vb != null) { 332 ret = (String) vb.getValue(getFacesContext()); 333 } else { 334 ret = entrySeparator; 335 } 336 return entrySeparator == null ? DEFAULT_ENTRY_SEPARATOR : entrySeparator; 337 } 338 339 public void setEntrySeparator(String entrySeparator) { 340 this.entrySeparator = entrySeparator; 341 } 342 343 public String getCssStyle() { 344 return cssStyle; 345 } 346 347 public void setCssStyle(String cssStyle) { 348 this.cssStyle = cssStyle; 349 } 350 351 public String getCssStyleClass() { 352 return cssStyleClass; 353 } 354 355 public void setCssStyleClass(String cssStyleClass) { 356 this.cssStyleClass = cssStyleClass; 357 } 358 359 public void setDisplayObsoleteEntries(Boolean displayObsoleteEntries) { 360 this.displayObsoleteEntries = displayObsoleteEntries; 361 } 362 363 public void setDisplayObsoleteEntries(boolean displayObsoleteEntries) { 364 this.displayObsoleteEntries = displayObsoleteEntries; 365 } 366 367 public void setQualifiedParentKeys(Boolean qualifiedParentKeys) { 368 this.qualifiedParentKeys = qualifiedParentKeys; 369 } 370 371 public String getDirectoryNameList() { 372 String ret; 373 ValueBinding vb = getValueBinding("directoryNameList"); 374 if (vb != null) { 375 ret = (String) vb.getValue(getFacesContext()); 376 } else { 377 ret = directoryNameList; 378 } 379 return ret; 380 } 381 382 public void setDirectoryNameList(String directoryNameList) { 383 this.directoryNameList = directoryNameList; 384 } 385 386}