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