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.nuxeo.common.utils.i18n.I18NUtils;
031import org.nuxeo.ecm.core.api.DocumentModel;
032import org.nuxeo.ecm.platform.ui.web.component.UISelectItems;
033
034/**
035 * Component that deals with a list of select items from a directory.
036 *
037 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
038 */
039public class UIDirectorySelectItems extends UISelectItems {
040
041    public static final String COMPONENT_TYPE = UIDirectorySelectItems.class.getName();
042
043    protected enum DirPropertyKeys {
044        directoryName, keySeparator, itemOrdering, allValues,
045        //
046        displayAll, displayObsoleteEntries, filter, localize, dbl10n;
047    }
048
049    // setters & getters
050
051    public Long getItemOrdering() {
052        return (Long) getStateHelper().eval(DirPropertyKeys.itemOrdering);
053    }
054
055    public void setItemOrdering(Long itemOrdering) {
056        getStateHelper().put(DirPropertyKeys.itemOrdering, itemOrdering);
057    }
058
059    public String getKeySeparator() {
060        return (String) getStateHelper().eval(DirPropertyKeys.keySeparator, ChainSelect.DEFAULT_KEY_SEPARATOR);
061    }
062
063    public void setKeySeparator(String keySeparator) {
064        getStateHelper().put(DirPropertyKeys.keySeparator, keySeparator);
065    }
066
067    public String getDirectoryName() {
068        return (String) getStateHelper().eval(DirPropertyKeys.directoryName);
069    }
070
071    public void setDirectoryName(String directoryName) {
072        getStateHelper().put(DirPropertyKeys.directoryName, directoryName);
073    }
074
075    public SelectItem[] getAllValues() {
076        return (SelectItem[]) getStateHelper().eval(DirPropertyKeys.allValues);
077    }
078
079    public void setAllValues(SelectItem[] allValues) {
080        getStateHelper().put(DirPropertyKeys.allValues, allValues);
081    }
082
083    @SuppressWarnings("boxing")
084    public boolean isDisplayAll() {
085        return (Boolean) getStateHelper().eval(DirPropertyKeys.displayAll, Boolean.TRUE);
086    }
087
088    @SuppressWarnings("boxing")
089    public void setDisplayAll(boolean displayAll) {
090        getStateHelper().put(DirPropertyKeys.displayAll, displayAll);
091    }
092
093    @SuppressWarnings("boxing")
094    public boolean isDisplayObsoleteEntries() {
095        return (Boolean) getStateHelper().eval(DirPropertyKeys.displayObsoleteEntries, Boolean.FALSE);
096    }
097
098    @SuppressWarnings("boxing")
099    public void setDisplayObsoleteEntries(boolean displayObsoleteEntries) {
100        getStateHelper().put(DirPropertyKeys.displayObsoleteEntries, displayObsoleteEntries);
101    }
102
103    public String getFilter() {
104        return (String) getStateHelper().eval(DirPropertyKeys.filter);
105    }
106
107    public void setFilter(String filter) {
108        getStateHelper().put(DirPropertyKeys.filter, filter);
109    }
110
111    @Override
112    @SuppressWarnings("boxing")
113    public boolean isLocalize() {
114        return (Boolean) getStateHelper().eval(DirPropertyKeys.localize, Boolean.FALSE);
115    }
116
117    @Override
118    @SuppressWarnings("boxing")
119    public void setLocalize(boolean localize) {
120        getStateHelper().put(DirPropertyKeys.localize, localize);
121    }
122
123    @Override
124    @SuppressWarnings("boxing")
125    public boolean isdbl10n() {
126        return (Boolean) getStateHelper().eval(DirPropertyKeys.dbl10n, Boolean.FALSE);
127    }
128
129    @Override
130    @SuppressWarnings("boxing")
131    public void setdbl10n(boolean dbl10n) {
132        getStateHelper().put(DirPropertyKeys.dbl10n, dbl10n);
133    }
134
135    @Override
136    public Object getValue() {
137        DirectorySelectItemsFactory f = new DirectorySelectItemsFactory() {
138
139            @Override
140            protected String getVar() {
141                return UIDirectorySelectItems.this.getVar();
142            }
143
144            @Override
145            protected DirectorySelectItem createSelectItem(String label, Long ordering) {
146                return UIDirectorySelectItems.this.createSelectItem(label, ordering);
147            }
148
149            @Override
150            protected String getDirectoryName() {
151                return UIDirectorySelectItems.this.getDirectoryName();
152            }
153
154            @Override
155            protected boolean isDisplayObsoleteEntries() {
156                return UIDirectorySelectItems.this.isDisplayObsoleteEntries();
157            }
158
159            @Override
160            protected String getFilter() {
161                return UIDirectorySelectItems.this.getFilter();
162            }
163
164            @Override
165            protected String[] retrieveSelectEntryId() {
166                return UIDirectorySelectItems.this.retrieveSelectEntryId();
167            }
168
169            @Override
170            protected Object retrieveItemLabel() {
171                return UIDirectorySelectItems.this.getItemLabel();
172            }
173
174            @Override
175            protected String retrieveLabelFromEntry(DocumentModel directoryEntry) {
176                return UIDirectorySelectItems.this.retrieveLabelFromEntry(directoryEntry);
177            }
178
179            @Override
180            protected Long retrieveOrderingFromEntry(DocumentModel directoryEntry) {
181                return UIDirectorySelectItems.this.retrieveOrderingFromEntry(directoryEntry);
182            }
183
184        };
185
186        List<DirectorySelectItem> items;
187        if (isDisplayAll()) {
188            items = f.createAllDirectorySelectItems();
189        } else {
190            Object value = getStateHelper().eval(PropertyKeys.value);
191            items = f.createDirectorySelectItems(value, getKeySeparator());
192        }
193
194        String ordering = getOrdering();
195        boolean caseSensitive = isCaseSensitive();
196        if (!StringUtils.isBlank(ordering)) {
197            Collections.sort(items, new DirectorySelectItemComparator(ordering, Boolean.valueOf(caseSensitive)));
198        }
199        DirectorySelectItem[] res = items.toArray(new DirectorySelectItem[0]);
200        if (isDisplayAll()) {
201            setAllValues(res);
202        }
203        return res;
204
205    }
206
207    protected DirectorySelectItem createSelectItem(String label, Long ordering) {
208        if (!isItemRendered()) {
209            return null;
210        }
211        Object valueObject = getItemValue();
212        String value = valueObject == null ? null : valueObject.toString();
213        if (isDisplayIdAndLabel() && label != null) {
214            label = value + getDisplayIdAndLabelSeparator() + label;
215        }
216        // make sure label is never blank
217        if (StringUtils.isBlank(label)) {
218            label = value;
219        }
220        String labelPrefix = getItemLabelPrefix();
221        if (!StringUtils.isBlank(labelPrefix)) {
222            label = labelPrefix + getItemLabelPrefixSeparator() + label;
223        }
224        String labelSuffix = getItemLabelSuffix();
225        if (!StringUtils.isBlank(labelSuffix)) {
226            label = label + getItemLabelSuffixSeparator() + labelSuffix;
227        }
228        return new DirectorySelectItem(value, label, ordering == null ? 0L : ordering.longValue(), isItemDisabled(),
229                isItemEscaped());
230    }
231
232    protected String[] retrieveSelectEntryId() {
233        // assume option id and vocabulary entry id will match
234        Object itemValue = getItemValue();
235        String id = itemValue != null ? itemValue.toString() : null;
236        if (StringUtils.isBlank(id)) {
237            return null;
238        }
239        String keySeparator = getKeySeparator();
240        if (!StringUtils.isBlank(keySeparator)) {
241            String[] split = id.split(keySeparator);
242            return split;
243        }
244        return new String[] {id};
245    }
246
247    protected String retrieveLabelFromEntry(DocumentModel docEntry) {
248        if (docEntry == null) {
249            return null;
250        }
251        String schema = docEntry.getSchemas()[0];
252        // compute label
253        Object labelObject = getItemLabel();
254        String label = labelObject != null ? labelObject.toString() : null;
255        FacesContext ctx = FacesContext.getCurrentInstance();
256        Locale locale = ctx.getViewRoot().getLocale();
257        if (StringUtils.isBlank(label)) {
258            if (isLocalize() && isdbl10n()) {
259                // lookup label property, hardcode the "label_" prefix for
260                // now
261                String defaultPattern = "label_en";
262                String pattern = "label_" + locale.getLanguage();
263                if (docEntry.getProperties(schema).containsKey(pattern)) {
264                    label = (String) docEntry.getProperties(schema).get(pattern);
265                } else {
266                    label = (String) docEntry.getProperties(schema).get(defaultPattern);
267                }
268            } else {
269                label = (String) docEntry.getProperties(schema).get("label");
270                if (isLocalize()) {
271                    label = translate(ctx, locale, label);
272                }
273            }
274        } else if (isLocalize()) {
275            label = translate(ctx, locale, label);
276        }
277        return label;
278    }
279
280    protected Long retrieveOrderingFromEntry(DocumentModel docEntry) {
281        Long ordering = getItemOrdering();
282        if (ordering != null) {
283            return ordering;
284        }
285        // fallback on default ordering key
286        if (docEntry == null) {
287            return null;
288        }
289        String schema = docEntry.getSchemas()[0];
290        try {
291            ordering = (Long) docEntry.getProperties(schema).get("ordering");
292        } catch (ClassCastException e) {
293            // nevermind
294        }
295        return ordering;
296    }
297
298    @Override
299    protected String translate(FacesContext context, Locale locale, String label) {
300        if (StringUtils.isBlank(label)) {
301            return label;
302        }
303        String bundleName = context.getApplication().getMessageBundle();
304        label = I18NUtils.getMessageString(bundleName, label, null, locale);
305        return label;
306    }
307
308}