001/*
002 * (C) Copyright 2010 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.ui.web.renderer;
020
021import java.io.IOException;
022
023import javax.faces.component.EditableValueHolder;
024import javax.faces.component.UIComponent;
025import javax.faces.component.ValueHolder;
026import javax.faces.context.FacesContext;
027import javax.faces.convert.Converter;
028import javax.faces.convert.ConverterException;
029
030import org.apache.commons.logging.Log;
031import org.apache.commons.logging.LogFactory;
032
033import com.sun.faces.renderkit.html_basic.CheckboxRenderer;
034import com.sun.faces.util.RequestStateManager;
035
036/**
037 * Renderer that does not ignore the converter set on the component on submit
038 *
039 * @author Anahide Tchertchian
040 */
041public class NXCheckboxRenderer extends CheckboxRenderer {
042
043    private static final Log log = LogFactory.getLog(NXCheckboxRenderer.class);
044
045    public static final String RENDERER_TYPE = "javax.faces.NXCheckbox";
046
047    @Override
048    public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue)
049            throws ConverterException {
050
051        String newValue = null;
052        if (submittedValue instanceof Boolean) {
053            newValue = ((Boolean) submittedValue).toString();
054        } else if (submittedValue instanceof String) {
055            newValue = (String) submittedValue;
056        } else if (submittedValue != null) {
057            log.error("Unsupported submitted value, should be a string or boolean: '" + submittedValue
058                    + "' => using false");
059        }
060
061        Converter converter = null;
062        // If there is a converter attribute, use it to to ask application
063        // instance for a converter with this identifer.
064        if (component instanceof ValueHolder) {
065            converter = ((ValueHolder) component).getConverter();
066        }
067
068        if (converter != null) {
069            // If the conversion eventually falls to needing to use EL type
070            // coercion,
071            // make sure our special ConverterPropertyEditor knows about this
072            // value.
073            RequestStateManager.set(context, RequestStateManager.TARGET_COMPONENT_ATTRIBUTE_NAME, component);
074            return converter.getAsObject(context, component, newValue);
075        } else {
076            return Boolean.valueOf(newValue);
077        }
078    }
079
080    @Override
081    protected void getEndTextToRender(FacesContext context, UIComponent component, String currentValue)
082            throws IOException {
083        String val = currentValue;
084        // hack to make sure checkbox state is restored correctly from bound value on ajax request
085        if (component instanceof EditableValueHolder && context.getPartialViewContext().isAjaxRequest()) {
086            Object reset = component.getAttributes().get("resetOnAjax");
087            if ((reset instanceof Boolean && Boolean.TRUE.equals(reset))
088                    || (reset instanceof String && Boolean.parseBoolean((String) reset))) {
089                EditableValueHolder c = (EditableValueHolder) component;
090                c.resetValue();
091                val = getCurrentValue(context, component);
092            }
093        }
094        super.getEndTextToRender(context, component, val);
095    }
096
097}