/* * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Anahide Tchertchian */ package org.nuxeo.ecm.platform.ui.web.directory; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.el.PropertyNotFoundException; import javax.faces.model.ListDataModel; import javax.faces.model.SelectItem; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.directory.DirectoryException; import org.nuxeo.ecm.directory.Session; import org.nuxeo.ecm.platform.ui.web.component.SelectItemsFactory; import org.nuxeo.ecm.platform.ui.web.component.VariableManager; /** * @since 6.0 */ public abstract class DirectorySelectItemsFactory extends SelectItemsFactory { private static final Log log = LogFactory.getLog(DirectorySelectItemsFactory.class); @Override protected abstract String getVar(); protected abstract String getDirectoryName(); protected abstract String getFilter(); protected abstract boolean isDisplayObsoleteEntries(); /** * @since 9.1 */ protected abstract boolean isNotDisplayDefaultOption(); protected abstract DirectorySelectItem createSelectItem(String label, Long ordering); protected abstract String[] retrieveSelectEntryId(); protected abstract Object retrieveItemLabel(); protected abstract String retrieveLabelFromEntry(DocumentModel directoryEntry); protected abstract Long retrieveOrderingFromEntry(DocumentModel directoryEntry); @SuppressWarnings({ "unchecked", "rawtypes" }) public List<DirectorySelectItem> createDirectorySelectItems(Object value, String separator) { Object varValue = saveRequestMapVarValue(); try { // build select items List<DirectorySelectItem> items = new ArrayList<DirectorySelectItem>(); String dirName = getDirectoryName(); if (StringUtils.isBlank(dirName)) { items.add(new DirectorySelectItem("", "ERROR: mising directoryName property " + "configuration on widget")); } else { try (Session directorySession = DirectorySelectItemFactory.getDirectorySession(dirName)) { if (directorySession != null) { if (value instanceof ListDataModel) { ListDataModel ldm = (ListDataModel) value; List<Object> entries = (List) ldm.getWrappedData(); for (Object entry : entries) { DirectorySelectItem res = createSelectItemFrom(directorySession, separator, entry); if (res != null) { items.add(res); } } } else if (value instanceof Collection) { Collection<Object> collection = (Collection<Object>) value; for (Object entry : collection) { DirectorySelectItem res = createSelectItemFrom(directorySession, separator, entry); if (res != null) { items.add(res); } } } else if (value instanceof Object[]) { Object[] entries = (Object[]) value; for (Object entry : entries) { DirectorySelectItem res = createSelectItemFrom(directorySession, separator, entry); if (res != null) { items.add(res); } } } } else { items.add(new DirectorySelectItem("", String.format( "ERROR: mising directorySession for directory '%s'", dirName))); } } } return items; } finally { restoreRequestMapVarValue(varValue); } } @SuppressWarnings("boxing") public List<DirectorySelectItem> createAllDirectorySelectItems() { return createAllDirectorySelectItems(ChainSelect.DEFAULT_KEY_SEPARATOR); } /** * @since 7.3 */ @SuppressWarnings("boxing") public List<DirectorySelectItem> createAllDirectorySelectItems(String separator) { Object varValue = saveRequestMapVarValue(); try { List<DirectorySelectItem> items = new ArrayList<DirectorySelectItem>(); try (Session directorySession = DirectorySelectItemFactory.getDirectorySession(getDirectoryName())) { if (directorySession != null) { Map<String, Serializable> filter = new HashMap<String, Serializable>(); if (!isDisplayObsoleteEntries()) { filter.put("obsolete", 0); } if (getFilter() != null) { filter.put("parentFilter", getFilter()); } DocumentModelList entries = directorySession.query(filter); for (DocumentModel entry : entries) { if (entry != null) { List<DocumentModel> entryL = new ArrayList<DocumentModel>(); entryL.add(entry); DirectorySelectItem res = createSelectItemForEntry(entry, separator, entry); if (res != null) { items.add(res); } } } } else { log.error("No session provided for directory, returning empty selection"); } } return items; } finally { restoreRequestMapVarValue(varValue); } } protected String[] retrieveEntryIdFrom(Object item) { Object varValue = saveRequestMapVarValue(); try { putIteratorToRequestParam(item); String[] id = retrieveSelectEntryId(); removeIteratorFromRequestParam(); return id; } finally { restoreRequestMapVarValue(varValue); } } protected DirectorySelectItem createSelectItemForEntry(Object itemValue, DocumentModel ... entries) { return createSelectItemForEntry(itemValue, ChainSelect.DEFAULT_KEY_SEPARATOR, entries); } /** * @since 7.4 */ protected DirectorySelectItem createSelectItemForEntry(Object itemValue, String separator, DocumentModel ... entries) { return createSelectItemForEntry(itemValue, separator, null, entries); } /** * @since 7.3 */ protected DirectorySelectItem createSelectItemForEntry(Object itemValue, String separator, String[] defaultLabels, DocumentModel ... entries) { if (defaultLabels != null && (entries.length != defaultLabels.length)) { throw new IllegalArgumentException("entryIds must be the same size that entries"); } String var = getVar(); String varEntry = var + "Entry"; Object varEntryExisting = VariableManager.saveRequestMapVarValue(varEntry); DirectorySelectItem selectItem = null; try { VariableManager.putVariableToRequestParam(var, itemValue); VariableManager.putVariableToRequestParam(varEntry, entries[entries.length - 1]); String label = ""; for (int i = 0; i < entries.length; i++) { final DocumentModel entry = entries[i]; if (label.length() != 0) { label += separator; } if (entry == null && defaultLabels != null) { label += defaultLabels[i]; } else { label += retrieveLabelFromEntry(entry); } } Long ordering = retrieveOrderingFromEntry(entries[entries.length - 1]); selectItem = createSelectItem(label, ordering); removeIteratorFromRequestParam(); VariableManager.removeVariableFromRequestParam(var); VariableManager.removeVariableFromRequestParam(varEntry); if (selectItem != null) { return selectItem; } else if (itemValue instanceof DirectorySelectItem) { // maybe lookup was not necessary return (DirectorySelectItem) itemValue; } return selectItem; } catch (PropertyNotFoundException e) { if (itemValue instanceof DirectorySelectItem) { // maybe lookup was not necessary return (DirectorySelectItem) itemValue; } else { throw e; } } finally { VariableManager.restoreRequestMapVarValue(varEntry, varEntryExisting); } } protected DirectorySelectItem createSelectItemFrom(Session session, Object entry) { return createSelectItemFrom(session, ChainSelect.DEFAULT_KEY_SEPARATOR, entry); } /** * @since 7.3 */ protected DirectorySelectItem createSelectItemFrom(Session session, String separator, Object entry) { String[] entryIds; if (entry instanceof String) { entryIds = new String[] {(String) entry}; } else { // first resolve entry id to be able to lookup // corresponding doc entry entryIds = retrieveEntryIdFrom(entry); } if (entryIds == null || entryIds.length == 0) { return null; } try { DocumentModel[] docEntries = new DocumentModel[entryIds.length]; int i = 0; for (String entryId : entryIds) { DocumentModel docEntry = session.getEntry(entryId); docEntries[i] = docEntry; i++; } if (docEntries == null || docEntries.length == 0) { putIteratorToRequestParam(entry); Object labelObject = retrieveItemLabel(); String label = labelObject == null ? null : String.valueOf(labelObject); if (StringUtils.isBlank(label) && entry != null) { label = entry.toString(); } DirectorySelectItem item = createSelectItem(label, Long.valueOf(0L)); removeIteratorFromRequestParam(); return item; } return createSelectItemForEntry(entry, separator, entryIds, docEntries); } catch (DirectoryException e) { } return null; } @Override public SelectItem createSelectItem() { throw new IllegalArgumentException("Use createSelectDirectoryItems instead"); } }