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