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