001/*
002 * (C) Copyright 2014 Nuxeo SA (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-2.1.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 *     Anahide Tchertchian
016 */
017package org.nuxeo.ecm.platform.contentview.jsf.facelets.plugins;
018
019import java.io.Serializable;
020import java.util.ArrayList;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Locale;
024import java.util.Map;
025
026import javax.el.ValueExpression;
027import javax.faces.view.facelets.CompositeFaceletHandler;
028import javax.faces.view.facelets.FaceletContext;
029import javax.faces.view.facelets.FaceletHandler;
030
031import org.nuxeo.ecm.platform.forms.layout.api.Widget;
032import org.nuxeo.ecm.platform.forms.layout.api.WidgetSelectOption;
033import org.nuxeo.ecm.platform.forms.layout.api.impl.WidgetSelectOptionsImpl;
034import org.nuxeo.ecm.platform.forms.layout.facelets.FaceletHandlerHelper;
035import org.nuxeo.ecm.platform.forms.layout.facelets.plugins.AbstractSelectWidgetTypeHandler;
036import org.nuxeo.ecm.platform.ui.web.tag.handler.LeafFaceletHandler;
037import org.nuxeo.ecm.platform.ui.web.util.ComponentTagUtils;
038
039/**
040 * @since 6.0
041 */
042public abstract class SelectAggregateWidgetTypeHandler extends AbstractSelectWidgetTypeHandler {
043
044    private static final String LABELS = "optionLabels";
045
046    private static final long serialVersionUID = 1L;
047
048    protected enum AggregatePropertyMappings {
049        itemCount;
050    }
051
052    @Override
053    protected FaceletHandler getOptionsFaceletHandler(FaceletContext ctx, FaceletHandlerHelper helper, Widget widget,
054            WidgetSelectOption[] selectOptions) {
055        FaceletHandler leaf = new LeafFaceletHandler();
056        List<FaceletHandler> selectItems = new ArrayList<FaceletHandler>();
057        FaceletHandler firstItem = getFirstHandler(ctx, helper, widget, leaf);
058        final boolean hasOtherOptions = selectOptions != null && selectOptions.length > 0;
059        if (firstItem != null) {
060            selectItems.add(firstItem);
061        }
062        FaceletHandler widgetPropsHandler = getWidgetPropsHandler(ctx, helper, widget, leaf, hasOtherOptions);
063        if (widgetPropsHandler != null) {
064            selectItems.add(widgetPropsHandler);
065        }
066        return new CompositeFaceletHandler(selectItems.toArray(new FaceletHandler[0]));
067    }
068
069    @Override
070    protected List<String> getExcludedProperties() {
071        List<String> res = super.getExcludedProperties();
072        for (AggregatePropertyMappings mapping : AggregatePropertyMappings.values()) {
073            res.add(mapping.name());
074        }
075        return res;
076    }
077
078    @Override
079    protected Map<String, Serializable> getOptionProperties(FaceletContext ctx, Widget widget,
080            WidgetSelectOption selectOption) {
081        Map<String, Serializable> props = super.getOptionProperties(ctx, widget, selectOption);
082        props.put(SelectPropertyMappings.itemLabelSuffix.name(),
083                widget.getProperty(AggregatePropertyMappings.itemCount.name()));
084        return props;
085    }
086
087    // redefined to merge selectOptions property and options put on widget
088    // definition
089    protected FaceletHandler getWidgetPropsHandler(FaceletContext ctx, FaceletHandlerHelper helper, Widget widget,
090            FaceletHandler nextHandler, boolean hasOtherOptions) {
091
092        if (!hasOtherOptions) {
093            return super.getWidgetPropsHandler(ctx, helper, widget, nextHandler);
094        }
095
096        if (shouldAddWidgetPropsHandler(widget)) {
097            WidgetSelectOption selectOption = new WidgetSelectOptionsImpl(
098                    widget.getProperty(SelectPropertyMappings.selectOptions.name()),
099                    (String) widget.getProperty(SelectPropertyMappings.var.name()),
100                    String.format(
101                            "#{%s[%s]}",
102                            LABELS,
103                            ComponentTagUtils.getBareValueName((String) widget.getProperty(SelectPropertyMappings.itemValue.name()))),
104                    (String) widget.getProperty(SelectPropertyMappings.itemValue.name()),
105                    widget.getProperty(SelectPropertyMappings.itemDisabled.name()),
106                    widget.getProperty(SelectPropertyMappings.itemRendered.name()));
107            return getOptionFaceletHandler(ctx, helper, widget, selectOption, nextHandler);
108        }
109        return null;
110    }
111
112    @Override
113    protected FaceletHandler getComponentFaceletHandler(FaceletContext ctx, FaceletHandlerHelper helper, Widget widget,
114            FaceletHandler componentHandler) {
115        WidgetSelectOption[] selectOptions = widget.getSelectOptions();
116        if (selectOptions != null && selectOptions.length != 0) {
117            List<String> blockedPatterns = new ArrayList<String>(1);
118            blockedPatterns.add(LABELS);
119            Map<String, String> labels = new HashMap<String, String>();
120            for (WidgetSelectOption selectOption : selectOptions) {
121                if (selectOption == null) {
122                    continue;
123                }
124                Map<String, String> l10n_labels = selectOption.getItemLabels();
125                boolean done = false;
126                if (l10n_labels != null && !l10n_labels.isEmpty()) {
127                    Locale locale = ctx.getFacesContext().getViewRoot().getLocale();
128                    if (l10n_labels.containsKey(locale.getLanguage()) | l10n_labels.containsKey("en")) {
129                        if (l10n_labels.containsKey(locale.getLanguage())) {
130                            labels.put(selectOption.getItemValue(), l10n_labels.get(locale.getLanguage()));
131                        } else {
132                            labels.put(selectOption.getItemValue(), l10n_labels.get("en"));
133                        }
134                        done = true;
135                    }
136                }
137                if (!done) {
138                    labels.put(selectOption.getItemValue(), selectOption.getItemLabel());
139                }
140            }
141            Map<String, ValueExpression> variables = new HashMap<String, ValueExpression>();
142            variables.put(LABELS, ctx.getExpressionFactory().createValueExpression(labels, HashMap.class));
143            return helper.getAliasTagHandler(widget.getTagConfigId(), variables, blockedPatterns, componentHandler);
144        } else {
145            return componentHandler;
146        }
147    }
148
149}