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 *     <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
016 *
017 * $Id: DirectorySelectManyWidgetTypeHandler.java 30416 2008-02-21 19:10:37Z atchertchian $
018 */
019
020package org.nuxeo.ecm.platform.forms.layout.facelets.plugins;
021
022import java.io.Serializable;
023import java.util.ArrayList;
024import java.util.List;
025import java.util.Map;
026
027import javax.faces.component.html.HtmlColumn;
028import javax.faces.component.html.HtmlDataTable;
029import javax.faces.component.html.HtmlOutputText;
030import javax.faces.component.html.HtmlSelectManyListbox;
031import javax.faces.view.facelets.ComponentHandler;
032import javax.faces.view.facelets.CompositeFaceletHandler;
033import javax.faces.view.facelets.FaceletContext;
034import javax.faces.view.facelets.FaceletHandler;
035import javax.faces.view.facelets.TagAttribute;
036import javax.faces.view.facelets.TagAttributes;
037import javax.faces.view.facelets.TagConfig;
038
039import org.nuxeo.ecm.platform.forms.layout.api.BuiltinWidgetModes;
040import org.nuxeo.ecm.platform.forms.layout.api.FieldDefinition;
041import org.nuxeo.ecm.platform.forms.layout.api.Widget;
042import org.nuxeo.ecm.platform.forms.layout.api.exceptions.WidgetException;
043import org.nuxeo.ecm.platform.forms.layout.facelets.FaceletHandlerHelper;
044import org.nuxeo.ecm.platform.forms.layout.facelets.ValueExpressionHelper;
045import org.nuxeo.ecm.platform.ui.web.component.list.UIEditableList;
046import org.nuxeo.ecm.platform.ui.web.component.seam.UIHtmlText;
047import org.nuxeo.ecm.platform.ui.web.directory.DirectoryEntryOutputComponent;
048
049import com.sun.faces.facelets.tag.TagAttributesImpl;
050
051/**
052 * Select many directory widget
053 *
054 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
055 */
056public class DirectorySelectManyWidgetTypeHandler extends AbstractDirectorySelectWidgetTypeHandler {
057
058    private static final long serialVersionUID = 1L;
059
060    protected String getEditComponentType() {
061        return HtmlSelectManyListbox.COMPONENT_TYPE;
062    }
063
064    @Override
065    public FaceletHandler getFaceletHandler(FaceletContext ctx, TagConfig tagConfig, Widget widget,
066            FaceletHandler[] subHandlers) throws WidgetException {
067        String mode = widget.getMode();
068        if (BuiltinWidgetModes.EDIT.equals(mode)) {
069            return super.getFaceletHandler(ctx, tagConfig, widget, subHandlers, getEditComponentType());
070        }
071
072        FaceletHandlerHelper helper = new FaceletHandlerHelper(ctx, tagConfig);
073        FaceletHandler leaf = getNextHandler(ctx, tagConfig, widget, subHandlers, helper);
074        String widgetName = widget.getName();
075        String widgetTagConfigId = widget.getTagConfigId();
076
077        // build value attribute for iteration component
078        String valueAttributeName = "value";
079        Map<String, Serializable> properties = widget.getProperties();
080        TagAttribute valueAttr = null;
081        if (properties.containsKey("value")) {
082            valueAttr = helper.createAttribute(valueAttributeName, (String) properties.get("value"));
083        }
084        FieldDefinition[] fields = widget.getFieldDefinitions();
085        if (fields != null && fields.length > 0) {
086            FieldDefinition field = fields[0];
087            valueAttr = helper.createAttribute(valueAttributeName,
088                    ValueExpressionHelper.createExpressionString(widget.getValueName(), field));
089        }
090        if (valueAttr == null) {
091            // don't bother
092            return leaf;
093        }
094
095        // build directory item attributes, using widget properties
096        List<TagAttribute> attrs = new ArrayList<TagAttribute>();
097        for (Map.Entry<String, Serializable> property : properties.entrySet()) {
098            if (!"value".equals(property.getKey())) {
099                Serializable value = property.getValue();
100                TagAttribute attr = null;
101                if (value instanceof String) {
102                    attr = helper.createAttribute(property.getKey(), (String) value);
103                } else if (value != null) {
104                    attr = helper.createAttribute(property.getKey(), value.toString());
105                }
106                if (attr != null) {
107                    attrs.add(attr);
108                }
109            }
110        }
111        if (BuiltinWidgetModes.isLikePlainMode(mode)) {
112            attrs.add(helper.createAttribute("value", "#{model.rowData}"));
113        } else {
114            attrs.add(helper.createAttribute("value", "#{item}"));
115        }
116        TagAttributes dirEntryAttrs = FaceletHandlerHelper.getTagAttributes(attrs);
117        ComponentHandler dirEntry = helper.getHtmlComponentHandler(widgetTagConfigId, dirEntryAttrs, leaf,
118                DirectoryEntryOutputComponent.COMPONENT_TYPE, null);
119
120        if (BuiltinWidgetModes.isLikePlainMode(mode)) {
121            // use an iteration and a comma to separate items instead of an
122            // HTML table component
123            TagAttributes commaAttributes = FaceletHandlerHelper.getTagAttributes(
124                    helper.createAttribute("value", ", "),
125                    helper.createAttribute("rendered", "#{model.rowIndex < model.rowCount}"));
126            ComponentHandler commaHandler = helper.getHtmlComponentHandler(widgetTagConfigId, commaAttributes, leaf,
127                    HtmlOutputText.COMPONENT_TYPE, null);
128
129            CompositeFaceletHandler childHandler = new CompositeFaceletHandler(new FaceletHandler[] { dirEntry,
130                    commaHandler });
131
132            TagAttributes itAttributes = FaceletHandlerHelper.getTagAttributes(valueAttr,
133                    helper.createAttribute("model", "model"));
134            ComponentHandler itHandler = helper.getHtmlComponentHandler(widgetTagConfigId, itAttributes, childHandler,
135                    UIEditableList.COMPONENT_TYPE, null);
136
137            return itHandler;
138        } else {
139            // build a standard table
140            ComponentHandler columnEntry = helper.getHtmlComponentHandler(widgetTagConfigId,
141                    FaceletHandlerHelper.getTagAttributes(), dirEntry, HtmlColumn.COMPONENT_TYPE, null);
142
143            TagAttributes iterationAttributes = FaceletHandlerHelper.getTagAttributes(
144                    helper.createIdAttribute(widgetName), valueAttr, helper.createAttribute("var", "item"));
145
146            ComponentHandler table = helper.getHtmlComponentHandler(widgetTagConfigId, iterationAttributes,
147                    columnEntry, HtmlDataTable.COMPONENT_TYPE, null);
148
149            if (BuiltinWidgetModes.PDF.equals(mode)) {
150                // add a surrounding p:html tag handler
151                return helper.getHtmlComponentHandler(widgetTagConfigId, new TagAttributesImpl(new TagAttribute[0]),
152                        table, UIHtmlText.class.getName(), null);
153            } else {
154                return table;
155            }
156        }
157    }
158}