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