All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.bund.bva.isyfact.common.web.jsf.renderer.NoLabelHtmlCheckboxRenderer Maven / Gradle / Ivy

Go to download

Die IsyFact-Standards bilden das architektonische, technologische und methodische Fundament der IsyFact. Sie umfassen allgemeingültige und wiederverwendbare Konzepte und Komponenten, die für die Entwicklung beliebiger Fachanwendungen relevant sind.

There is a newer version: 6.2.0
Show newest version
/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 * The Federal Office of Administration (Bundesverwaltungsamt, BVA)
 * licenses this file to you under the Apache License, Version 2.0 (the
 * License). You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package de.bund.bva.isyfact.common.web.jsf.renderer;

import java.io.IOException;
import java.util.List;
import java.util.Set;

import javax.faces.component.UIComponent;
import javax.faces.component.UISelectBoolean;
import javax.faces.component.UISelectMany;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.model.SelectItem;
import javax.faces.model.SelectItemGroup;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.component.UserRoleUtils;
import org.apache.myfaces.component.html.ext.HtmlSelectManyCheckbox;
import org.apache.myfaces.custom.checkbox.HtmlCheckbox;
import org.apache.myfaces.renderkit.html.ext.HtmlCheckboxRenderer;
import org.apache.myfaces.shared_tomahawk.component.DisplayValueOnlyCapable;
import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;

/**
 * Erweitert den Standard Checkbox Renderer von Tomahawk, damit kein Label gerendert wird. Dies übernimmt die
 * Composite Component.
 * 
 * Durchgeführte Änderungen:
 * 
 * Methode {@link #renderSingleCheckbox(FacesContext, HtmlCheckbox)} rendert kein Label mehr.
 * 
 * @author Capgemini, Andreas Hörning
 * @version $Id: NoLabelHtmlCheckboxRenderer.java 123758 2014-10-10 10:01:14Z sdm_ahoerning $
 */
public class NoLabelHtmlCheckboxRenderer extends HtmlCheckboxRenderer {

    private static final Log log = LogFactory.getLog(HtmlCheckboxRenderer.class);

    private static final String PAGE_DIRECTION = "pageDirection";

    private static final String LINE_DIRECTION = "lineDirection";

    private static final String LAYOUT_SPREAD = "spread";

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        if (context == null)
            throw new NullPointerException("context");
        if (component == null)
            throw new NullPointerException("component");

        if (component instanceof HtmlCheckbox) {
            renderSingleCheckbox(context, (HtmlCheckbox) component);
        } else if (component instanceof DisplayValueOnlyCapable
            && HtmlRendererUtils.isDisplayValueOnly(component)) {
            HtmlRendererUtils.renderDisplayValueOnlyForSelects(context, component, true);
        } else if (component instanceof UISelectMany) {
            String layout = getLayout((UISelectMany) component);
            if (layout != null && layout.equals(LAYOUT_SPREAD)) {
                return; // checkbox inputs are rendered by spread checkbox components
            } else {
                super.encodeEnd(context, component);
            }
        } else if (component instanceof UISelectBoolean) {
            super.encodeEnd(context, component);
        } else {
            throw new IllegalArgumentException("Unsupported component class "
                + component.getClass().getName());
        }
    }

    @Override
    public void renderCheckboxList(FacesContext facesContext, UISelectMany selectMany) throws IOException {
        final String layout = getLayout(selectMany);
        if (layout != null) {
            Converter converter = getConverter(facesContext, selectMany);
            if (layout.equals(PAGE_DIRECTION)) {
                renderCheckboxListVertically(facesContext, selectMany, converter);
            } else if (layout.equals(LINE_DIRECTION)) {
                renderCheckboxListHorizontally(facesContext, selectMany, converter);
            } else {
                log.error("Wrong layout attribute for component " + selectMany.getClientId(facesContext)
                    + ": " + layout);
            }
        }
    }

    @Override
    protected void renderCheckboxListHorizontally(FacesContext facesContext, UISelectMany selectMany,
        Converter converter) throws IOException {
        Set lookupSet =
            RendererUtils.getSubmittedValuesAsSet(facesContext, selectMany, converter, selectMany);
        boolean useSubmittedValues = lookupSet != null;
        if (!useSubmittedValues) {
            lookupSet = RendererUtils.getSelectedValuesAsSet(facesContext, selectMany, converter, selectMany);
        }

        ResponseWriter writer = facesContext.getResponseWriter();
        writer.startElement(HTML.TABLE_ELEM, selectMany);
        HtmlRendererUtils.renderHTMLAttributes(writer, selectMany, HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
        HtmlRendererUtils.writeIdIfNecessary(writer, selectMany, facesContext);

        final int numRows = getLayoutWidth(selectMany);
        for (int i = 0; i < numRows; i++) {
            renderRowForHorizontal(facesContext, selectMany, converter, lookupSet, writer, numRows, i);
        }

        writer.endElement(HTML.TABLE_ELEM);
    }

    @Override
    protected void renderRowForHorizontal(FacesContext facesContext, UISelectMany selectMany,
        Converter converter, Set lookupSet, ResponseWriter writer, int totalRows, int rowNum)
        throws IOException {

        writer.startElement(HTML.TR_ELEM, selectMany);
        int colNum = 0;
        List items = RendererUtils.getSelectItemList(selectMany);
        for (int count = rowNum; count < items.size(); count++) {
            int mod = count % totalRows;
            if (mod == rowNum) {
                colNum++;
                SelectItem selectItem = (SelectItem) items.get(count);
                writer.startElement(HTML.TD_ELEM, selectMany);
                renderGroupOrItemCheckbox(facesContext, selectMany, selectItem, lookupSet != null, lookupSet,
                    converter, false);
                writer.endElement(HTML.TD_ELEM);
            }
        }
        int totalItems = items.size();
        int totalCols = (totalItems / totalRows);
        if (totalItems % totalRows != 0) {
            totalCols++;
        }
        if (colNum < totalCols) {
            writer.startElement(HTML.TD_ELEM, selectMany);
            writer.endElement(HTML.TD_ELEM);
        }
        writer.endElement(HTML.TR_ELEM);
    }

    @Override
    protected void renderCheckboxListVertically(FacesContext facesContext, UISelectMany selectMany,
        Converter converter) throws IOException {

        Set lookupSet =
            RendererUtils.getSubmittedValuesAsSet(facesContext, selectMany, converter, selectMany);
        boolean useSubmittedValues = lookupSet != null;
        if (!useSubmittedValues) {
            lookupSet = RendererUtils.getSelectedValuesAsSet(facesContext, selectMany, converter, selectMany);
        }

        ResponseWriter writer = facesContext.getResponseWriter();
        writer.startElement(HTML.TABLE_ELEM, selectMany);
        HtmlRendererUtils.renderHTMLAttributes(writer, selectMany, HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
        HtmlRendererUtils.writeIdIfNecessary(writer, selectMany, facesContext);

        List items = RendererUtils.getSelectItemList(selectMany);
        int totalItems = items.size();
        for (int count = 0; count < totalItems; count++) {
            writer.startElement(HTML.TR_ELEM, selectMany);
            final int numCols = getLayoutWidth(selectMany);
            for (int i = 0; i < numCols; i++) {
                writer.startElement(HTML.TD_ELEM, selectMany);
                if (count < totalItems) {
                    SelectItem selectItem = (SelectItem) items.get(count);
                    renderGroupOrItemCheckbox(facesContext, selectMany, selectItem, lookupSet != null,
                        lookupSet, converter, true);
                }
                writer.endElement(HTML.TD_ELEM);
                if (i < numCols - 1) {
                    count += 1;
                }
            }
            writer.endElement(HTML.TR_ELEM);
        }
        writer.endElement(HTML.TABLE_ELEM);
    }

    @Override
    protected void renderGroupOrItemCheckbox(FacesContext facesContext, UIComponent uiComponent,
        SelectItem selectItem, boolean useSubmittedValues, Set lookupSet, Converter converter,
        boolean pageDirectionLayout) throws IOException {
        ResponseWriter writer = facesContext.getResponseWriter();

        boolean isSelectItemGroup = (selectItem instanceof SelectItemGroup);

        if (isSelectItemGroup) {
            SelectItemGroup selectItemGroup = (SelectItemGroup) selectItem;
            renderCheckboxGroup(facesContext, uiComponent, selectItemGroup, useSubmittedValues, lookupSet,
                converter, pageDirectionLayout);
        } else {
            UISelectMany selectMany = (UISelectMany) uiComponent;
            Object itemValue = selectItem.getValue(); // TODO : Check here for getSubmittedValue. Look at
                                                      // RendererUtils.getValue
            String itemStrValue = getItemStringValue(facesContext, selectMany, converter, itemValue);

            boolean checked =
                (useSubmittedValues && lookupSet.contains(itemStrValue))
                    || (!useSubmittedValues && lookupSet.contains(itemValue));

            boolean disabled = selectItem.isDisabled();

            writer.startElement(HTML.LABEL_ELEM, selectMany);
            renderLabelClassIfNecessary(facesContext, selectMany, disabled);
            renderCheckbox(facesContext, selectMany, itemStrValue, disabled, checked, false, 0);
            writer.write(HTML.NBSP_ENTITY);
            if (selectItem.isEscape()) {
                writer.writeText(selectItem.getLabel(), null);
            } else {
                writer.write(selectItem.getLabel());
            }
            writer.endElement(HTML.LABEL_ELEM);
        }
    }

    @Override
    protected void renderLabelClassIfNecessary(FacesContext facesContext, UISelectMany selectMany,
        boolean disabled) throws IOException {
        String labelClass = null;
        boolean componentDisabled = isDisabled(facesContext, selectMany);
        if (componentDisabled || disabled) {
            labelClass = (String) selectMany.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
        } else {
            labelClass = (String) selectMany.getAttributes().get(JSFAttr.ENABLED_CLASS_ATTR);
        }
        if (labelClass != null) {
            ResponseWriter writer = facesContext.getResponseWriter();
            writer.writeAttribute("class", labelClass, "labelClass");
        }
    }

    @Override
    protected void renderCheckboxGroup(FacesContext facesContext, UIComponent uiComponent,
        SelectItemGroup selectItemGroup, boolean useSubmittedValues, Set lookupSet, Converter converter,
        boolean pageDirectionLayout) throws IOException {
        ResponseWriter writer = facesContext.getResponseWriter();
        UISelectMany selectMany = (UISelectMany) uiComponent;
        writer.startElement(HTML.TABLE_ELEM, selectMany);
        if (pageDirectionLayout)
            writer.startElement(HTML.TR_ELEM, selectMany);
        writer.startElement(HTML.TD_ELEM, selectMany);
        if (selectItemGroup.isEscape()) {
            writer.writeText(selectItemGroup.getLabel(), HTML.LABEL_ATTR);
        } else {
            writer.write(selectItemGroup.getLabel());
        }
        writer.endElement(HTML.TD_ELEM);

        if (pageDirectionLayout) {
            writer.endElement(HTML.TR_ELEM);
            writer.startElement(HTML.TR_ELEM, selectMany);
        }
        writer.startElement(HTML.TD_ELEM, selectMany);
        writer.startElement(HTML.TABLE_ELEM, selectMany);
        writer.writeAttribute(HTML.BORDER_ATTR, "0", null);

        SelectItem[] selectItems = selectItemGroup.getSelectItems();
        for (int i = 0; i < selectItems.length; i++) {
            renderGroupOrItemCheckbox(facesContext, selectMany, selectItems[i], useSubmittedValues,
                lookupSet, converter, pageDirectionLayout);
        }

        writer.endElement(HTML.TABLE_ELEM);
        writer.endElement(HTML.TD_ELEM);
        if (pageDirectionLayout)
            writer.endElement(HTML.TR_ELEM);
        writer.endElement(HTML.TABLE_ELEM);
    }

    /**
     * Determines the layout setting. Defaults to lineDirection if not specified.
     * @param selectMany
     *            the component
     * @return the layout
     */
    @Override
    protected String getLayout(UISelectMany selectMany) {
        String layout = super.getLayout(selectMany);
        if (layout == null) {
            layout = LINE_DIRECTION;
        }
        return layout;
    }

    /**
     * Gets the layout width. Returns the default layout width of 1 if the layout width is not set or is less
     * than 1.
     * @param selectMany
     *            the component
     * @return the layout width
     */
    @Override
    protected int getLayoutWidth(UISelectMany selectMany) {
        String layoutWidthString = null;
        if (selectMany instanceof HtmlSelectManyCheckbox) {
            layoutWidthString = ((HtmlSelectManyCheckbox) selectMany).getLayoutWidth();
        } else {
            layoutWidthString = (String) selectMany.getAttributes().get(JSFAttr.LAYOUT_WIDTH_ATTR);
        }
        final int defaultLayoutWidth = 1;
        int layoutWidth = defaultLayoutWidth;
        try {
            if (layoutWidthString != null && layoutWidthString.trim().length() > 0) {
                layoutWidth = Integer.parseInt(layoutWidthString);
            }
            if (layoutWidth < 1) {
                layoutWidth = defaultLayoutWidth;
            }
        } catch (Exception e) {
            layoutWidth = defaultLayoutWidth;
        }
        return layoutWidth;
    }

    @Override
    protected void renderSingleCheckbox(FacesContext facesContext, HtmlCheckbox checkbox) throws IOException {
        String forAttr = checkbox.getFor();
        if (forAttr == null) {
            throw new IllegalStateException("mandatory attribute 'for'");
        }
        int index = checkbox.getIndex();
        if (index < 0) {
            throw new IllegalStateException("positive index must be given");
        }

        UIComponent uiComponent = search(forAttr, checkbox);
        if (uiComponent == null) {
            throw new IllegalStateException("Could not find component '" + forAttr
                + "' (calling findComponent on component '" + checkbox.getClientId(facesContext) + "')");
        }
        if (!(uiComponent instanceof UISelectMany)) {
            throw new IllegalStateException("UISelectMany expected");
        }

        UISelectMany uiSelectMany = (UISelectMany) uiComponent;
        Converter converter = getConverter(facesContext, uiSelectMany);
        List selectItemList = RendererUtils.getSelectItemList(uiSelectMany);
        if (index >= selectItemList.size()) {
            throw new IndexOutOfBoundsException("index " + index + " >= " + selectItemList.size());
        }

        SelectItem selectItem = (SelectItem) selectItemList.get(index);
        Object itemValue = selectItem.getValue();
        String itemStrValue = getItemStringValue(facesContext, uiSelectMany, converter, itemValue);

        // TODO: we must cache this Set!
        Set lookupSet =
            RendererUtils.getSubmittedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany);

        boolean useSubmittedValues = (lookupSet != null);
        if (!useSubmittedValues) {
            lookupSet =
                RendererUtils.getSelectedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany);
        }

        ResponseWriter writer = facesContext.getResponseWriter();

        // renderCheckbox(facesContext,
        // uiSelectMany,
        // itemStrValue,
        // selectItem.getLabel(),
        // isDisabled(facesContext,uiSelectMany),
        // lookupSet.contains(itemStrValue), true);

        String itemId =
            renderCheckbox(facesContext, uiSelectMany, itemStrValue, isDisabled(facesContext, uiSelectMany),
                lookupSet.contains(itemStrValue), false, index);

        // Render the
        // label element after the input
        boolean componentDisabled = isDisabled(facesContext, uiSelectMany);
        boolean itemDisabled = selectItem.isDisabled();
        boolean disabled = (componentDisabled || itemDisabled);

        // Es werden keine Labels gerendert.
        // HtmlRendererUtils.renderLabel(writer, uiSelectMany, itemId, selectItem.getLabel(), disabled);

    }

    @Override
    protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent) {
        if (!UserRoleUtils.isEnabledOnUserRole(uiComponent)) {
            return true;
        } else {
            return super.isDisabled(facesContext, uiComponent);
        }
    }

    @Override
    public void decode(FacesContext facesContext, UIComponent uiComponent) {
        if (uiComponent instanceof HtmlCheckbox) {
            // nothing to decode
        } else {
            super.decode(facesContext, uiComponent);
        }
    }

    @Override
    protected String getItemStringValue(FacesContext facesContext, UISelectMany selectMany,
        Converter converter, Object itemValue) {
        String itemStrValue;
        if (converter == null) {
            itemStrValue = itemValue.toString();
        } else {
            itemStrValue = converter.getAsString(facesContext, selectMany, itemValue);
        }
        return itemStrValue;
    }

    /**
     * Overrides HtmlCheckboxRendererBase to handle valueType attribute on UISelectMany.
     */
    @Override
    public Object getConvertedValue(FacesContext facesContext, UIComponent component, Object submittedValue)
        throws ConverterException {
        RendererUtils.checkParamValidity(facesContext, component, null);

        if (component instanceof UISelectMany) {
            // invoke getConvertedUISelectManyValue() with considerValueType = true
            return RendererUtils.getConvertedUISelectManyValue(facesContext, (UISelectMany) component,
                submittedValue, true);
        } else {
            // component is not a UISelectMany --> no change needed
            return super.getConvertedValue(facesContext, component, submittedValue);
        }
    }

    /**
     * Overrides HtmlCheckboxRendererBase to handle valueType attribute on UISelectMany.
     */
    @Override
    protected Converter getConverter(FacesContext facesContext, UIComponent component) {
        if (component instanceof UISelectMany) {
            // invoke findUISelectManyConverterFailsafe() with considerValueType = true
            return HtmlRendererUtils.findUISelectManyConverterFailsafe(facesContext, component, true);
        } else {
            // component is not a UISelectMany --> no change needed
            return super.getConverter(facesContext, component);
        }
    }

    /**
     * Sucht eine UIComponent über die integrierte JSF-Suche oder relativ.
     * 
     * @param searchExpression
     *            Die Suchanfrage.
     * @param base
     *            Von welchem Element aus gesucht wird.
     * @return Die UI-Component.
     */
    private UIComponent search(String searchExpression, UIComponent base) {

        UIComponent uiComponent = null;

        if (searchExpression.startsWith("relative:")) {
            // Relative Suche

            String search = searchExpression.substring("relative:".length());
            String[] searchParts = search.split(":");

            uiComponent = base;

            for (String searchPart : searchParts) {
                if (searchPart.equals("super")) {
                    uiComponent = uiComponent.getParent();
                } else {
                    for (UIComponent uiComponentChild : uiComponent.getChildren()) {
                        if (searchPart.equals(uiComponentChild.getId())) {
                            uiComponent = uiComponentChild;
                            break;
                        }
                    }
                }

            }

        } else {
            uiComponent = base.findComponent(searchExpression);
        }

        return uiComponent;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy