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 *     btatar
018 *     Anahide Tchertchian
019 *
020 * $Id$
021 */
022
023package org.nuxeo.ecm.platform.forms.layout.facelets.plugins;
024
025import java.io.IOException;
026import java.util.ArrayList;
027import java.util.List;
028
029import javax.faces.component.UIComponent;
030import javax.faces.component.html.HtmlOutputText;
031import javax.faces.component.html.HtmlSelectBooleanCheckbox;
032import javax.faces.view.facelets.ComponentHandler;
033import javax.faces.view.facelets.CompositeFaceletHandler;
034import javax.faces.view.facelets.FaceletContext;
035import javax.faces.view.facelets.FaceletHandler;
036import javax.faces.view.facelets.TagAttribute;
037import javax.faces.view.facelets.TagAttributes;
038import javax.faces.view.facelets.TagConfig;
039
040import org.nuxeo.ecm.platform.forms.layout.api.BuiltinWidgetModes;
041import org.nuxeo.ecm.platform.forms.layout.api.FieldDefinition;
042import org.nuxeo.ecm.platform.forms.layout.api.Widget;
043import org.nuxeo.ecm.platform.forms.layout.api.exceptions.WidgetException;
044import org.nuxeo.ecm.platform.forms.layout.facelets.FaceletHandlerHelper;
045import org.nuxeo.ecm.platform.forms.layout.facelets.ValueExpressionHelper;
046import org.nuxeo.ecm.platform.ui.web.component.seam.UIHtmlText;
047import org.nuxeo.ecm.platform.ui.web.renderer.NXCheckboxRenderer;
048
049import com.sun.faces.facelets.tag.TagAttributesImpl;
050
051/**
052 * Checkbox widget that generates a checkbox for a boolean value in edit mode, and displays the boolean value in view
053 * mode.
054 * <p>
055 * In view mode, it expects the messages 'label.yes' and 'label.no' to be present in a bundle called 'messages' for
056 * internationalization, when the bound value is computed from field definitions.
057 */
058public class CheckboxWidgetTypeHandler extends AbstractWidgetTypeHandler {
059
060    public CheckboxWidgetTypeHandler(TagConfig config) {
061        super(config);
062    }
063
064    @Override
065    public void apply(FaceletContext ctx, UIComponent parent, Widget widget) throws WidgetException, IOException {
066        FaceletHandlerHelper helper = new FaceletHandlerHelper(tagConfig);
067        String mode = widget.getMode();
068        String widgetId = widget.getId();
069        String widgetName = widget.getName();
070        String widgetTagConfigId = widget.getTagConfigId();
071        FaceletHandler leaf = getNextHandler(ctx, tagConfig, widget, null, helper);
072        if (BuiltinWidgetModes.EDIT.equals(mode)) {
073            TagAttributes attributes = helper.getTagAttributes(widgetId, widget);
074            ComponentHandler input = helper.getHtmlComponentHandler(widgetTagConfigId, attributes, leaf,
075                    HtmlSelectBooleanCheckbox.COMPONENT_TYPE, NXCheckboxRenderer.RENDERER_TYPE);
076            String msgId = FaceletHandlerHelper.generateMessageId(ctx, widgetName);
077            ComponentHandler message = helper.getMessageComponentHandler(widgetTagConfigId, msgId, widgetId, null);
078            FaceletHandler[] handlers = { input, message };
079            FaceletHandler h = new CompositeFaceletHandler(handlers);
080            h.apply(ctx, parent);
081        } else {
082            TagAttributes attributes = getViewTagAttributes(ctx, helper, widgetId, widget,
083                    !BuiltinWidgetModes.isLikePlainMode(mode));
084            // default on text for other modes
085            ComponentHandler output = helper.getHtmlComponentHandler(widgetTagConfigId, attributes, leaf,
086                    HtmlOutputText.COMPONENT_TYPE, null);
087            if (BuiltinWidgetModes.PDF.equals(mode)) {
088                // add a surrounding p:html tag handler
089                FaceletHandler h = helper.getHtmlComponentHandler(widgetTagConfigId, new TagAttributesImpl(
090                        new TagAttribute[0]), output, UIHtmlText.class.getName(), null);
091                h.apply(ctx, parent);
092            } else {
093                output.apply(ctx, parent);
094            }
095        }
096    }
097
098    /**
099     * Return tag attributes after having replaced the usual value expression for the 'value' field by a specific
100     * expression to display the boolean value as an internationalized label.
101     */
102    protected TagAttributes getViewTagAttributes(FaceletContext ctx, FaceletHandlerHelper helper, String id,
103            Widget widget, boolean addId) {
104        List<TagAttribute> attrs = new ArrayList<TagAttribute>();
105        FieldDefinition[] fields = widget.getFieldDefinitions();
106        if (fields != null && fields.length > 0) {
107            FieldDefinition field = fields[0];
108            String bareExpression = ValueExpressionHelper.createBareExpressionString(widget.getValueName(), field);
109            String bundleName = ctx.getFacesContext().getApplication().getMessageBundle();
110            String messageYes = bundleName + "['label.yes']";
111            String messageNo = bundleName + "['label.no']";
112            String expression = "#{" + bareExpression + " ? " + messageYes + " : " + messageNo + "}";
113            TagAttribute valueAttr = helper.createAttribute("value", expression);
114            attrs.add(valueAttr);
115        }
116
117        // fill with widget properties
118        List<TagAttribute> propertyAttrs = helper.getTagAttributes(widget.getProperties(), null, true,
119                widget.getType(), widget.getTypeCategory(), widget.getMode());
120        if (propertyAttrs != null) {
121            attrs.addAll(propertyAttrs);
122        }
123        TagAttributes widgetAttrs = FaceletHandlerHelper.getTagAttributes(attrs);
124        // handle id
125        if (!addId) {
126            return widgetAttrs;
127        } else {
128            return FaceletHandlerHelper.addTagAttribute(widgetAttrs, helper.createAttribute("id", id));
129        }
130
131    }
132}