001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
016 *
017 * $Id: UIDirectorySelectItems.java 29556 2008-01-23 00:59:39Z jcarsique $
018 */
019
020package org.nuxeo.ecm.platform.ui.web.directory;
021
022import java.util.Collections;
023import java.util.List;
024import java.util.Locale;
025
026import javax.faces.context.FacesContext;
027import javax.faces.model.SelectItem;
028
029import org.apache.commons.lang.StringUtils;
030import org.apache.commons.logging.Log;
031import org.apache.commons.logging.LogFactory;
032import org.nuxeo.common.utils.i18n.I18NUtils;
033import org.nuxeo.ecm.core.api.DocumentModel;
034import org.nuxeo.ecm.platform.ui.web.component.UISelectItems;
035
036/**
037 * Component that deals with a list of select items from a directory.
038 *
039 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
040 */
041public class UIDirectorySelectItems extends UISelectItems {
042
043    private static final Log log = LogFactory.getLog(UIDirectorySelectItems.class);
044
045    public static final String COMPONENT_TYPE = UIDirectorySelectItems.class.getName();
046
047    protected enum DirPropertyKeys {
048        directoryName, keySeparator, itemOrdering, allValues,
049        //
050        displayAll, displayObsoleteEntries, filter, localize, dbl10n;
051    }
052
053    // setters & getters
054
055    public Long getItemOrdering() {
056        return (Long) getStateHelper().eval(DirPropertyKeys.itemOrdering);
057    }
058
059    public void setItemOrdering(Long itemOrdering) {
060        getStateHelper().put(DirPropertyKeys.itemOrdering, itemOrdering);
061    }
062
063    public String getKeySeparator() {
064        return (String) getStateHelper().eval(DirPropertyKeys.keySeparator, ChainSelect.DEFAULT_KEY_SEPARATOR);
065    }
066
067    public void setKeySeparator(String keySeparator) {
068        getStateHelper().put(DirPropertyKeys.keySeparator, keySeparator);
069    }
070
071    public String getDirectoryName() {
072        return (String) getStateHelper().eval(DirPropertyKeys.directoryName);
073    }
074
075    public void setDirectoryName(String directoryName) {
076        getStateHelper().put(DirPropertyKeys.directoryName, directoryName);
077    }
078
079    public SelectItem[] getAllValues() {
080        return (SelectItem[]) getStateHelper().eval(DirPropertyKeys.allValues);
081    }
082
083    public void setAllValues(SelectItem[] allValues) {
084        getStateHelper().put(DirPropertyKeys.allValues, allValues);
085    }
086
087    @SuppressWarnings("boxing")
088    public boolean isDisplayAll() {
089        return (Boolean) getStateHelper().eval(DirPropertyKeys.displayAll, Boolean.TRUE);
090    }
091
092    @SuppressWarnings("boxing")
093    public void setDisplayAll(boolean displayAll) {
094        getStateHelper().put(DirPropertyKeys.displayAll, displayAll);
095    }
096
097    @SuppressWarnings("boxing")
098    public boolean isDisplayObsoleteEntries() {
099        return (Boolean) getStateHelper().eval(DirPropertyKeys.displayObsoleteEntries, Boolean.FALSE);
100    }
101
102    @SuppressWarnings("boxing")
103    public void setDisplayObsoleteEntries(boolean displayObsoleteEntries) {
104        getStateHelper().put(DirPropertyKeys.displayObsoleteEntries, displayObsoleteEntries);
105    }
106
107    public String getFilter() {
108        return (String) getStateHelper().eval(DirPropertyKeys.filter);
109    }
110
111    public void setFilter(String filter) {
112        getStateHelper().put(DirPropertyKeys.filter, filter);
113    }
114
115    @Override
116    @SuppressWarnings("boxing")
117    public boolean isLocalize() {
118        return (Boolean) getStateHelper().eval(DirPropertyKeys.localize, Boolean.FALSE);
119    }
120
121    @Override
122    @SuppressWarnings("boxing")
123    public void setLocalize(boolean localize) {
124        getStateHelper().put(DirPropertyKeys.localize, localize);
125    }
126
127    @Override
128    @SuppressWarnings("boxing")
129    public boolean isdbl10n() {
130        return (Boolean) getStateHelper().eval(DirPropertyKeys.dbl10n, Boolean.FALSE);
131    }
132
133    @Override
134    @SuppressWarnings("boxing")
135    public void setdbl10n(boolean dbl10n) {
136        getStateHelper().put(DirPropertyKeys.dbl10n, dbl10n);
137    }
138
139    @Override
140    public Object getValue() {
141        DirectorySelectItemsFactory f = new DirectorySelectItemsFactory() {
142
143            @Override
144            protected String getVar() {
145                return UIDirectorySelectItems.this.getVar();
146            }
147
148            @Override
149            protected DirectorySelectItem createSelectItem(String label, Long ordering) {
150                return UIDirectorySelectItems.this.createSelectItem(label, ordering);
151            }
152
153            @Override
154            protected String getDirectoryName() {
155                return UIDirectorySelectItems.this.getDirectoryName();
156            }
157
158            @Override
159            protected boolean isDisplayObsoleteEntries() {
160                return UIDirectorySelectItems.this.isDisplayObsoleteEntries();
161            }
162
163            @Override
164            protected String getFilter() {
165                return UIDirectorySelectItems.this.getFilter();
166            }
167
168            @Override
169            protected String[] retrieveSelectEntryId() {
170                return UIDirectorySelectItems.this.retrieveSelectEntryId();
171            }
172
173            @Override
174            protected Object retrieveItemLabel() {
175                return UIDirectorySelectItems.this.getItemLabel();
176            }
177
178            @Override
179            protected String retrieveLabelFromEntry(DocumentModel directoryEntry) {
180                return UIDirectorySelectItems.this.retrieveLabelFromEntry(directoryEntry);
181            }
182
183            @Override
184            protected Long retrieveOrderingFromEntry(DocumentModel directoryEntry) {
185                return UIDirectorySelectItems.this.retrieveOrderingFromEntry(directoryEntry);
186            }
187
188        };
189
190        List<DirectorySelectItem> items;
191        if (isDisplayAll()) {
192            items = f.createAllDirectorySelectItems();
193        } else {
194            Object value = getStateHelper().eval(PropertyKeys.value);
195            items = f.createDirectorySelectItems(value, getKeySeparator());
196        }
197
198        String ordering = getOrdering();
199        boolean caseSensitive = isCaseSensitive();
200        if (!StringUtils.isBlank(ordering)) {
201            Collections.sort(items, new DirectorySelectItemComparator(ordering, Boolean.valueOf(caseSensitive)));
202        }
203        DirectorySelectItem[] res = items.toArray(new DirectorySelectItem[0]);
204        if (isDisplayAll()) {
205            setAllValues(res);
206        }
207        return res;
208
209    }
210
211    protected DirectorySelectItem createSelectItem(String label, Long ordering) {
212        if (!isItemRendered()) {
213            return null;
214        }
215        Object valueObject = getItemValue();
216        String value = valueObject == null ? null : valueObject.toString();
217        if (isDisplayIdAndLabel() && label != null) {
218            label = value + getDisplayIdAndLabelSeparator() + label;
219        }
220        // make sure label is never blank
221        if (StringUtils.isBlank(label)) {
222            label = value;
223        }
224        String labelPrefix = getItemLabelPrefix();
225        if (!StringUtils.isBlank(labelPrefix)) {
226            label = labelPrefix + getItemLabelPrefixSeparator() + label;
227        }
228        String labelSuffix = getItemLabelSuffix();
229        if (!StringUtils.isBlank(labelSuffix)) {
230            label = label + getItemLabelSuffixSeparator() + labelSuffix;
231        }
232        return new DirectorySelectItem(value, label, ordering == null ? 0L : ordering.longValue(), isItemDisabled(),
233                isItemEscaped());
234    }
235
236    protected String[] retrieveSelectEntryId() {
237        // assume option id and vocabulary entry id will match
238        Object itemValue = getItemValue();
239        String id = itemValue != null ? itemValue.toString() : null;
240        if (StringUtils.isBlank(id)) {
241            return null;
242        }
243        String keySeparator = getKeySeparator();
244        if (!StringUtils.isBlank(keySeparator)) {
245            String[] split = id.split(keySeparator);
246            return split;
247        }
248        return new String[] {id};
249    }
250
251    protected String retrieveLabelFromEntry(DocumentModel docEntry) {
252        if (docEntry == null) {
253            return null;
254        }
255        String schema = docEntry.getSchemas()[0];
256        // compute label
257        Object labelObject = getItemLabel();
258        String label = labelObject != null ? labelObject.toString() : null;
259        FacesContext ctx = FacesContext.getCurrentInstance();
260        Locale locale = ctx.getViewRoot().getLocale();
261        if (StringUtils.isBlank(label)) {
262            if (isLocalize() && isdbl10n()) {
263                // lookup label property, hardcode the "label_" prefix for
264                // now
265                String defaultPattern = "label_en";
266                String pattern = "label_" + locale.getLanguage();
267                label = (String) docEntry.getProperty(schema, pattern);
268                if (StringUtils.isBlank(label)) {
269                    label = (String) docEntry.getProperty(schema, defaultPattern);
270                }
271                if (StringUtils.isBlank(label)) {
272                    label = docEntry.getId();
273                    log.warn("Could not find label column for entry " + label + " (falling back on entry id)");
274                }
275            } else {
276                label = (String) docEntry.getProperties(schema).get("label");
277                if (isLocalize()) {
278                    label = translate(ctx, locale, label);
279                }
280            }
281        } else if (isLocalize()) {
282            label = translate(ctx, locale, label);
283        }
284        return label;
285    }
286
287    protected Long retrieveOrderingFromEntry(DocumentModel docEntry) {
288        Long ordering = getItemOrdering();
289        if (ordering != null) {
290            return ordering;
291        }
292        // fallback on default ordering key
293        if (docEntry == null) {
294            return null;
295        }
296        String schema = docEntry.getSchemas()[0];
297        try {
298            ordering = (Long) docEntry.getProperties(schema).get("ordering");
299        } catch (ClassCastException e) {
300            // nevermind
301        }
302        return ordering;
303    }
304
305    @Override
306    protected String translate(FacesContext context, Locale locale, String label) {
307        if (StringUtils.isBlank(label)) {
308            return label;
309        }
310        String bundleName = context.getApplication().getMessageBundle();
311        label = I18NUtils.getMessageString(bundleName, label, null, locale);
312        return label;
313    }
314
315}