001/* 002 * (C) Copyright 2014 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 * Anahide Tchertchian 018 */ 019package org.nuxeo.ecm.platform.ui.web.directory; 020 021import java.io.Serializable; 022import java.util.ArrayList; 023import java.util.Collection; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Map; 027 028import javax.el.PropertyNotFoundException; 029import javax.faces.model.ListDataModel; 030import javax.faces.model.SelectItem; 031 032import org.apache.commons.lang3.StringUtils; 033import org.apache.commons.logging.Log; 034import org.apache.commons.logging.LogFactory; 035import org.nuxeo.ecm.core.api.DocumentModel; 036import org.nuxeo.ecm.core.api.DocumentModelList; 037import org.nuxeo.ecm.directory.DirectoryException; 038import org.nuxeo.ecm.directory.Session; 039import org.nuxeo.ecm.platform.ui.web.component.SelectItemsFactory; 040import org.nuxeo.ecm.platform.ui.web.component.VariableManager; 041 042/** 043 * @since 6.0 044 */ 045public abstract class DirectorySelectItemsFactory extends SelectItemsFactory { 046 047 private static final Log log = LogFactory.getLog(DirectorySelectItemsFactory.class); 048 049 @Override 050 protected abstract String getVar(); 051 052 protected abstract String getDirectoryName(); 053 054 protected abstract String getFilter(); 055 056 protected abstract boolean isDisplayObsoleteEntries(); 057 058 /** 059 * @since 9.1 060 */ 061 protected abstract boolean isNotDisplayDefaultOption(); 062 063 protected abstract DirectorySelectItem createSelectItem(String label, Long ordering); 064 065 protected abstract String[] retrieveSelectEntryId(); 066 067 protected abstract Object retrieveItemLabel(); 068 069 protected abstract String retrieveLabelFromEntry(DocumentModel directoryEntry); 070 071 protected abstract Long retrieveOrderingFromEntry(DocumentModel directoryEntry); 072 073 @SuppressWarnings({ "unchecked", "rawtypes" }) 074 public List<DirectorySelectItem> createDirectorySelectItems(Object value, String separator) { 075 Object varValue = saveRequestMapVarValue(); 076 try { 077 // build select items 078 List<DirectorySelectItem> items = new ArrayList<DirectorySelectItem>(); 079 String dirName = getDirectoryName(); 080 if (StringUtils.isBlank(dirName)) { 081 items.add(new DirectorySelectItem("", "ERROR: mising directoryName property " 082 + "configuration on widget")); 083 } else { 084 try (Session directorySession = DirectorySelectItemFactory.getDirectorySession(dirName)) { 085 if (directorySession != null) { 086 if (value instanceof ListDataModel) { 087 ListDataModel ldm = (ListDataModel) value; 088 List<Object> entries = (List) ldm.getWrappedData(); 089 for (Object entry : entries) { 090 DirectorySelectItem res = createSelectItemFrom(directorySession, separator, entry); 091 if (res != null) { 092 items.add(res); 093 } 094 } 095 } else if (value instanceof Collection) { 096 Collection<Object> collection = (Collection<Object>) value; 097 for (Object entry : collection) { 098 DirectorySelectItem res = createSelectItemFrom(directorySession, separator, entry); 099 if (res != null) { 100 items.add(res); 101 } 102 } 103 } else if (value instanceof Object[]) { 104 Object[] entries = (Object[]) value; 105 for (Object entry : entries) { 106 DirectorySelectItem res = createSelectItemFrom(directorySession, separator, entry); 107 if (res != null) { 108 items.add(res); 109 } 110 } 111 } 112 } else { 113 items.add(new DirectorySelectItem("", String.format( 114 "ERROR: mising directorySession for directory '%s'", dirName))); 115 } 116 } 117 } 118 return items; 119 } finally { 120 restoreRequestMapVarValue(varValue); 121 } 122 } 123 124 @SuppressWarnings("boxing") 125 public List<DirectorySelectItem> createAllDirectorySelectItems() { 126 return createAllDirectorySelectItems(ChainSelect.DEFAULT_KEY_SEPARATOR); 127 } 128 129 /** 130 * @since 7.3 131 */ 132 @SuppressWarnings("boxing") 133 public List<DirectorySelectItem> createAllDirectorySelectItems(String separator) { 134 Object varValue = saveRequestMapVarValue(); 135 try { 136 List<DirectorySelectItem> items = new ArrayList<DirectorySelectItem>(); 137 try (Session directorySession = DirectorySelectItemFactory.getDirectorySession(getDirectoryName())) { 138 if (directorySession != null) { 139 Map<String, Serializable> filter = new HashMap<String, Serializable>(); 140 if (!isDisplayObsoleteEntries()) { 141 filter.put("obsolete", 0); 142 } 143 if (getFilter() != null) { 144 filter.put("parentFilter", getFilter()); 145 } 146 DocumentModelList entries = directorySession.query(filter); 147 for (DocumentModel entry : entries) { 148 if (entry != null) { 149 List<DocumentModel> entryL = new ArrayList<DocumentModel>(); 150 entryL.add(entry); 151 DirectorySelectItem res = createSelectItemForEntry(entry, separator, entry); 152 if (res != null) { 153 items.add(res); 154 } 155 } 156 } 157 } else { 158 log.error("No session provided for directory, returning empty selection"); 159 } 160 } 161 return items; 162 } finally { 163 restoreRequestMapVarValue(varValue); 164 } 165 } 166 167 protected String[] retrieveEntryIdFrom(Object item) { 168 Object varValue = saveRequestMapVarValue(); 169 try { 170 putIteratorToRequestParam(item); 171 String[] id = retrieveSelectEntryId(); 172 removeIteratorFromRequestParam(); 173 return id; 174 } finally { 175 restoreRequestMapVarValue(varValue); 176 } 177 } 178 179 protected DirectorySelectItem createSelectItemForEntry(Object itemValue, DocumentModel ... entries) { 180 return createSelectItemForEntry(itemValue, ChainSelect.DEFAULT_KEY_SEPARATOR, entries); 181 } 182 183 /** 184 * @since 7.4 185 */ 186 protected DirectorySelectItem createSelectItemForEntry(Object itemValue, String separator, DocumentModel ... entries) { 187 return createSelectItemForEntry(itemValue, separator, null, entries); 188 } 189 190 /** 191 * @since 7.3 192 */ 193 protected DirectorySelectItem createSelectItemForEntry(Object itemValue, String separator, String[] defaultLabels, DocumentModel ... entries) { 194 if (defaultLabels != null && (entries.length != defaultLabels.length)) { 195 throw new IllegalArgumentException("entryIds must be the same size that entries"); 196 } 197 String var = getVar(); 198 String varEntry = var + "Entry"; 199 Object varEntryExisting = VariableManager.saveRequestMapVarValue(varEntry); 200 201 DirectorySelectItem selectItem = null; 202 try { 203 VariableManager.putVariableToRequestParam(var, itemValue); 204 VariableManager.putVariableToRequestParam(varEntry, entries[entries.length - 1]); 205 String label = ""; 206 for (int i = 0; i < entries.length; i++) { 207 final DocumentModel entry = entries[i]; 208 if (label.length() != 0) { 209 label += separator; 210 } 211 if (entry == null && defaultLabels != null) { 212 label += defaultLabels[i]; 213 } else { 214 label += retrieveLabelFromEntry(entry); 215 } 216 } 217 Long ordering = retrieveOrderingFromEntry(entries[entries.length - 1]); 218 selectItem = createSelectItem(label, ordering); 219 removeIteratorFromRequestParam(); 220 VariableManager.removeVariableFromRequestParam(var); 221 VariableManager.removeVariableFromRequestParam(varEntry); 222 if (selectItem != null) { 223 return selectItem; 224 } else if (itemValue instanceof DirectorySelectItem) { 225 // maybe lookup was not necessary 226 return (DirectorySelectItem) itemValue; 227 } 228 return selectItem; 229 } catch (PropertyNotFoundException e) { 230 if (itemValue instanceof DirectorySelectItem) { 231 // maybe lookup was not necessary 232 return (DirectorySelectItem) itemValue; 233 } else { 234 throw e; 235 } 236 } finally { 237 VariableManager.restoreRequestMapVarValue(varEntry, varEntryExisting); 238 } 239 240 } 241 242 protected DirectorySelectItem createSelectItemFrom(Session session, Object entry) { 243 return createSelectItemFrom(session, ChainSelect.DEFAULT_KEY_SEPARATOR, entry); 244 } 245 246 /** 247 * @since 7.3 248 */ 249 protected DirectorySelectItem createSelectItemFrom(Session session, String separator, Object entry) { 250 String[] entryIds; 251 if (entry instanceof String) { 252 entryIds = new String[] {(String) entry}; 253 } else { 254 // first resolve entry id to be able to lookup 255 // corresponding doc entry 256 entryIds = retrieveEntryIdFrom(entry); 257 } 258 if (entryIds == null || entryIds.length == 0) { 259 return null; 260 } 261 try { 262 DocumentModel[] docEntries = new DocumentModel[entryIds.length]; 263 int i = 0; 264 for (String entryId : entryIds) { 265 DocumentModel docEntry = session.getEntry(entryId); 266 docEntries[i] = docEntry; 267 i++; 268 } 269 if (docEntries == null || docEntries.length == 0) { 270 putIteratorToRequestParam(entry); 271 Object labelObject = retrieveItemLabel(); 272 String label = labelObject == null ? null : String.valueOf(labelObject); 273 if (StringUtils.isBlank(label) && entry != null) { 274 label = entry.toString(); 275 } 276 DirectorySelectItem item = createSelectItem(label, Long.valueOf(0L)); 277 removeIteratorFromRequestParam(); 278 return item; 279 } 280 return createSelectItemForEntry(entry, separator, entryIds, docEntries); 281 } catch (DirectoryException e) { 282 } 283 return null; 284 } 285 286 @Override 287 public SelectItem createSelectItem() { 288 throw new IllegalArgumentException("Use createSelectDirectoryItems instead"); 289 } 290 291}