001/*
002 * (C) Copyright 2006-2007 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 *     Nuxeo - initial API and implementation
018 *
019 * $Id: DirectoryAwareComponent.java 29914 2008-02-06 14:46:40Z atchertchian $
020 */
021
022package org.nuxeo.ecm.platform.ui.web.directory;
023
024import java.io.Serializable;
025import java.util.ArrayList;
026import java.util.Collections;
027import java.util.HashMap;
028import java.util.LinkedHashMap;
029import java.util.List;
030import java.util.Map;
031
032import javax.el.ELException;
033import javax.el.ValueExpression;
034import javax.faces.FacesException;
035import javax.faces.component.UIInput;
036import javax.faces.context.FacesContext;
037import javax.faces.model.SelectItem;
038
039import org.apache.commons.lang.StringUtils;
040
041/**
042 * Directory-aware abstract component.
043 *
044 * @author <a href="mailto:glefter@nuxeo.com">George Lefter</a>
045 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
046 */
047public abstract class DirectoryAwareComponent extends UIInput {
048
049    protected String directoryName;
050
051    protected Map<String, SelectItem> options;
052
053    protected Boolean displayIdAndLabel;
054
055    protected Boolean displayObsoleteEntries;
056
057    protected Boolean localize;
058
059    protected Boolean notDisplayDefaultOption;
060
061    protected Boolean displayValueOnly;
062
063    protected String displayValueOnlyStyle;
064
065    protected String displayValueOnlyStyleClass;
066
067    /**
068     * This field is used to specify what to display from the entry of a directory,the id, label or both of them.
069     */
070    protected String display;
071
072    protected String onchange;
073
074    protected String onclick;
075
076    protected String onselect;
077
078    protected String filter;
079
080    protected String size;
081
082    protected String ordering;
083
084    protected VocabularyEntryList directoryValues;
085
086    protected Boolean caseSensitive;
087
088    protected String getStringValue(String name, String defaultValue) {
089        ValueExpression ve = getValueExpression(name);
090        if (ve != null) {
091            try {
092                return (String) ve.getValue(getFacesContext().getELContext());
093            } catch (ELException e) {
094                throw new FacesException(e);
095            }
096        } else {
097            return defaultValue;
098        }
099    }
100
101    protected Boolean getBooleanValue(String name, boolean defaultValue) {
102        ValueExpression ve = getValueExpression(name);
103        if (ve != null) {
104            try {
105                return !Boolean.FALSE.equals(ve.getValue(getFacesContext().getELContext()));
106            } catch (ELException e) {
107                throw new FacesException(e);
108            }
109        } else {
110            return defaultValue;
111        }
112    }
113
114    public String getDirectoryName() {
115        if (directoryName != null) {
116            return directoryName;
117        }
118        return getStringValue("directoryName", null);
119    }
120
121    public void setDirectoryName(String directoryName) {
122        this.directoryName = directoryName;
123    }
124
125    public Boolean getDisplayIdAndLabel() {
126        if (displayIdAndLabel != null) {
127            return displayIdAndLabel;
128        }
129        return getBooleanValue("displayIdAndLabel", false);
130    }
131
132    public void setDisplayIdAndLabel(Boolean displayIdAndLabel) {
133        this.displayIdAndLabel = displayIdAndLabel;
134    }
135
136    public Boolean getLocalize() {
137        if (localize != null) {
138            return localize;
139        }
140        return getBooleanValue("localize", false);
141    }
142
143    public void setLocalize(Boolean localize) {
144        this.localize = localize;
145    }
146
147    public Boolean getCaseSensitive() {
148        if (caseSensitive != null) {
149            return caseSensitive;
150        }
151        return getBooleanValue("caseSensitive", false);
152    }
153
154    public void setCaseSensitive(Boolean caseSensitive) {
155        this.caseSensitive = caseSensitive;
156    }
157
158    public Map<String, SelectItem> getOptions() {
159        // rebuild systematically since a single component may be rendered
160        // several times in the same page for different directories
161        VocabularyEntryList directoryValues = getDirectoryValues();
162        String directoryName = getDirectoryName();
163
164        options = new LinkedHashMap<String, SelectItem>();
165        if (StringUtils.isEmpty(directoryName) && directoryValues == null) {
166            return options;
167            // throw new RuntimeException("directoryName and directoryValues
168            // cannot be both null");
169        }
170
171        Map<String, Serializable> filter = new HashMap<String, Serializable>();
172        String parentFilter = getFilter();
173        if (parentFilter != null) {
174            filter.put("parent", parentFilter);
175        }
176        if (!getDisplayObsoleteEntries()) {
177            filter.put("obsolete", 0);
178        }
179
180        List<DirectorySelectItem> optionList;
181        if (!StringUtils.isEmpty(directoryName)) {
182            optionList = DirectoryHelper.instance().getSelectItems(directoryName, filter, getLocalize());
183        } else if (directoryValues != null) {
184            optionList = DirectoryHelper.getSelectItems(directoryValues, filter, getLocalize());
185        } else {
186            optionList = new ArrayList<DirectorySelectItem>();
187        }
188        String ordering = getOrdering();
189        Boolean caseSensitive = getCaseSensitive();
190        if (ordering != null && !"".equals(ordering)) {
191            Collections.sort(optionList, new DirectorySelectItemComparator(ordering, caseSensitive));
192        }
193
194        for (DirectorySelectItem item : optionList) {
195            options.put((String) item.getValue(), item);
196        }
197
198        return options;
199    }
200
201    public void setOptions(Map<String, SelectItem> options) {
202        this.options = options;
203    }
204
205    public Boolean getDisplayObsoleteEntries() {
206        if (displayObsoleteEntries != null) {
207            return displayObsoleteEntries;
208        }
209        return getBooleanValue("displayObsoleteEntries", false);
210    }
211
212    public void setDisplayObsoleteEntries(Boolean displayObsoleteEntries) {
213        this.displayObsoleteEntries = displayObsoleteEntries;
214    }
215
216    public Boolean getNotDisplayDefaultOption() {
217        if (notDisplayDefaultOption != null) {
218            return notDisplayDefaultOption;
219        }
220        return getBooleanValue("notDisplayDefaultOption", false);
221    }
222
223    public void setNotDisplayDefaultOption(Boolean notDisplayDefaultOption) {
224        this.notDisplayDefaultOption = notDisplayDefaultOption;
225    }
226
227    public Boolean getDisplayValueOnly() {
228        if (displayValueOnly != null) {
229            return displayValueOnly;
230        }
231        return getBooleanValue("displayValueOnly", false);
232    }
233
234    public void setDisplayValueOnly(Boolean displayValueOnly) {
235        this.displayValueOnly = displayValueOnly;
236    }
237
238    public String getDisplayValueOnlyStyle() {
239        if (displayValueOnlyStyle != null) {
240            return displayValueOnlyStyle;
241        }
242        return getStringValue("displayValueOnlyStyle", null);
243    }
244
245    public void setDisplayValueOnlyStyle(String displayValueOnlyStyle) {
246        this.displayValueOnlyStyle = displayValueOnlyStyle;
247    }
248
249    public String getDisplayValueOnlyStyleClass() {
250        if (displayValueOnlyStyleClass != null) {
251            return displayValueOnlyStyleClass;
252        }
253        return getStringValue("displayValueOnlyStyleClass", null);
254    }
255
256    public void setDisplayValueOnlyStyleClass(String displayValueOnlyStyleClass) {
257        this.displayValueOnlyStyleClass = displayValueOnlyStyleClass;
258    }
259
260    public String getDisplay() {
261        if (display != null) {
262            return display;
263        }
264        return getStringValue("display", null);
265    }
266
267    public void setDisplay(String display) {
268        this.display = display;
269    }
270
271    public String getOnchange() {
272        if (onchange != null) {
273            return onchange;
274        }
275        return getStringValue("onchange", null);
276    }
277
278    public void setOnchange(String onchange) {
279        this.onchange = onchange;
280    }
281
282    public String getOnclick() {
283        if (onclick != null) {
284            return onclick;
285        }
286        return getStringValue("onclick", null);
287    }
288
289    public void setOnclick(String onclick) {
290        this.onclick = onclick;
291    }
292
293    public String getOnselect() {
294        if (onselect != null) {
295            return onselect;
296        }
297        return getStringValue("onselect", null);
298    }
299
300    public void setOnselect(String onselect) {
301        this.onselect = onselect;
302    }
303
304    public String getFilter() {
305        if (filter != null) {
306            return filter;
307        }
308        return getStringValue("filter", null);
309    }
310
311    public void setFilter(String filter) {
312        this.filter = filter;
313    }
314
315    public String getSize() {
316        if (size != null) {
317            return size;
318        }
319        return getStringValue("size", null);
320    }
321
322    public void setSize(String size) {
323        this.size = size;
324    }
325
326    public String getOrdering() {
327        if (ordering != null) {
328            return ordering;
329        }
330        return getStringValue("ordering", "label");
331    }
332
333    public void setOrdering(String ordering) {
334        this.ordering = ordering;
335    }
336
337    public VocabularyEntryList getDirectoryValues() {
338        ValueExpression ve = getValueExpression("directoryValues");
339        if (ve != null) {
340            try {
341                return (VocabularyEntryList) ve.getValue(getFacesContext().getELContext());
342            } catch (ELException e) {
343                throw new FacesException(e);
344            }
345        } else {
346            // default value
347            return null;
348        }
349    }
350
351    public void setDirectoryValues(VocabularyEntryList directoryValues) {
352        this.directoryValues = directoryValues;
353    }
354
355    @Override
356    public Object saveState(FacesContext context) {
357        Object[] values = new Object[19];
358        values[0] = super.saveState(context);
359        values[1] = directoryName;
360        values[2] = options;
361        values[3] = displayIdAndLabel;
362        values[4] = displayObsoleteEntries;
363        values[5] = localize;
364        values[6] = notDisplayDefaultOption;
365        values[7] = displayValueOnly;
366        values[8] = displayValueOnlyStyle;
367        values[9] = displayValueOnlyStyleClass;
368        values[10] = display;
369        values[11] = onchange;
370        values[12] = filter;
371        values[13] = size;
372        values[14] = ordering;
373        values[15] = directoryValues;
374        values[16] = caseSensitive;
375        values[17] = onclick;
376        values[18] = onselect;
377        return values;
378    }
379
380    @SuppressWarnings("unchecked")
381    @Override
382    public void restoreState(FacesContext context, Object state) {
383        Object[] values = (Object[]) state;
384        super.restoreState(context, values[0]);
385        directoryName = (String) values[1];
386        options = (Map<String, SelectItem>) values[2];
387        displayIdAndLabel = (Boolean) values[3];
388        displayObsoleteEntries = (Boolean) values[4];
389        localize = (Boolean) values[5];
390        notDisplayDefaultOption = (Boolean) values[6];
391        displayValueOnly = (Boolean) values[7];
392        displayValueOnlyStyle = (String) values[8];
393        displayValueOnlyStyleClass = (String) values[9];
394        display = (String) values[10];
395        onchange = (String) values[11];
396        filter = (String) values[12];
397        size = (String) values[13];
398        ordering = (String) values[14];
399        directoryValues = (VocabularyEntryList) values[15];
400        caseSensitive = (Boolean) values[16];
401        onclick = (String) values[17];
402        onselect = (String) values[18];
403    }
404
405    public Boolean getBooleanProperty(String key, Boolean defaultValue) {
406        Map<String, Object> map = getAttributes();
407        Boolean value = (Boolean) map.get(key);
408        if (value == null) {
409            value = defaultValue;
410        }
411        return value;
412    }
413
414    public String getStringProperty(String key, String defaultValue) {
415        Map<String, Object> map = getAttributes();
416        String value = (String) map.get(key);
417        if (value == null) {
418            value = defaultValue;
419        }
420        return value;
421    }
422
423}