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 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.platform.ui.web.directory;
021
022import java.io.IOException;
023import java.util.ArrayList;
024import java.util.List;
025import java.util.Locale;
026import java.util.Map;
027
028import javax.faces.component.UIComponent;
029import javax.faces.context.FacesContext;
030import javax.faces.context.ResponseWriter;
031import javax.faces.render.Renderer;
032
033import org.apache.commons.logging.Log;
034import org.apache.commons.logging.LogFactory;
035import org.nuxeo.common.utils.i18n.I18NUtils;
036
037import com.sun.faces.renderkit.RenderKitUtils;
038
039/**
040 * @author <a href="mailto:glefter@nuxeo.com">George Lefter</a>
041 */
042public class ChainSelectListboxRenderer extends Renderer {
043
044    @SuppressWarnings("unused")
045    private static final Log log = LogFactory.getLog(ChainSelectListboxRenderer.class);
046
047    @Override
048    public void decode(FacesContext facesContext, UIComponent component) {
049    }
050
051    @Override
052    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
053        ChainSelectListboxComponent comp = (ChainSelectListboxComponent) component;
054        ResponseWriter writer = context.getResponseWriter();
055        Boolean displayValueOnly = comp.getChain().getBooleanProperty("displayValueOnly", false);
056        if (displayValueOnly) {
057            return;
058        }
059        encodeInput(context, writer, comp);
060    }
061
062    private static void encodeInput(FacesContext context, ResponseWriter writer, ChainSelectListboxComponent comp)
063            throws IOException {
064        String id = comp.getClientId(context);
065        ChainSelect chain = comp.getChain();
066        String cssStyleClass = comp.getStringProperty("cssStyleClass", null);
067        String cssStyle = comp.getStringProperty("cssStyle", null);
068        String onchange = comp.getStringProperty("onchange", null);
069        // XXX hack: add onchange set on the chain select
070        String chainOnchange = chain.getOnchange();
071        if (chainOnchange != null) {
072            if (onchange == null) {
073                onchange = chainOnchange;
074            } else {
075                if (onchange.endsWith(";")) {
076                    onchange += chainOnchange;
077                } else {
078                    onchange += "; " + chainOnchange;
079                }
080            }
081        }
082
083        boolean multiSelect = comp.getBooleanProperty("multiSelect", false);
084        String size = comp.getStringProperty("size", null);
085        boolean displayIdAndLabel = comp.getBooleanProperty("displayIdAndLabel", false);
086        String displayIdAndLabelSeparator = comp.getStringProperty("displayIdAndLabelSeparator", " ");
087        boolean localize = comp.getBooleanProperty("localize", false);
088        String display = comp.getStringProperty("display", "");
089
090        if (chain.getBooleanProperty("displayValueOnly", false)) {
091            return;
092        }
093
094        writer.startElement("select", comp);
095        writer.writeAttribute("id", id, "id");
096        writer.writeAttribute("name", id, "name");
097        if (onchange != null) {
098            writer.writeAttribute("onchange", onchange, "onchange");
099        }
100        if (cssStyleClass != null) {
101            writer.writeAttribute("class", cssStyleClass, "class");
102        }
103        if (cssStyle != null) {
104            writer.writeAttribute("style", cssStyle, "style");
105        }
106        if (multiSelect) {
107            writer.writeAttribute("multiple", "true", "multiple");
108        }
109        if (size != null && Integer.valueOf(size) > 0) {
110            writer.writeAttribute("size", size, "size");
111        }
112        RenderKitUtils.renderOnchange(context, comp, false);
113
114        List<String> valueList = new ArrayList<String>();
115
116        int index = comp.getIndex();
117        Selection[] selections = chain.getSelections();
118        if (selections != null) {
119            for (Selection selection : selections) {
120                valueList.add(selection.getColumnValue(index));
121            }
122        }
123
124        String optionsLabel = translate(context, "label.vocabulary.selectValue");
125
126        writer.startElement("option", comp);
127        writer.writeAttribute("value", "", "value");
128        writer.writeText(optionsLabel, null);
129        writer.endElement("option");
130        writer.write("\n");
131
132        Map<String, DirectorySelectItem> options = comp.getOptions();
133        if (options != null) {
134            for (DirectorySelectItem item : options.values()) {
135                String optionId = (String) item.getValue();
136                String optionLabel = item.getLabel();
137
138                writer.startElement("option", comp);
139                writer.writeAttribute("value", optionId, "value");
140                if (valueList.contains(optionId)) {
141                    writer.writeAttribute("selected", "true", "selected");
142                }
143                if (localize) {
144                    optionLabel = translate(context, optionLabel);
145                }
146                writer.writeText(
147                        DirectoryHelper.instance().getOptionValue(optionId, optionLabel, display, displayIdAndLabel,
148                                displayIdAndLabelSeparator), null);
149                writer.endElement("option");
150            }
151        }
152        writer.endElement("select");
153        writer.write("\n");
154    }
155
156    protected static String translate(FacesContext context, String label) {
157        String bundleName = context.getApplication().getMessageBundle();
158        Locale locale = context.getViewRoot().getLocale();
159        label = I18NUtils.getMessageString(bundleName, label, null, locale);
160        return label;
161    }
162}