Package org.apache.beehive.netui.tags.html

Source Code of org.apache.beehive.netui.tags.html.RadioButtonGroup$RadioButtonGroupPrefixHandler

/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed 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.
*
* $Header:$
*/
package org.apache.beehive.netui.tags.html;

import org.apache.beehive.netui.util.internal.InternalStringBuilder;

import org.apache.beehive.netui.pageflow.ProcessPopulate;
import org.apache.beehive.netui.script.common.DataAccessProviderStack;
import org.apache.beehive.netui.tags.naming.FormDataNameInterceptor;
import org.apache.beehive.netui.tags.naming.IndexedNameInterceptor;
import org.apache.beehive.netui.tags.naming.PrefixNameInterceptor;
import org.apache.beehive.netui.tags.rendering.StringBuilderRenderAppender;
import org.apache.beehive.netui.tags.rendering.TagRenderingBase;
import org.apache.beehive.netui.tags.rendering.WriteRenderAppender;
import org.apache.beehive.netui.util.Bundle;
import org.apache.beehive.netui.util.logging.Logger;
import org.apache.beehive.netui.util.tags.GroupOption;

import javax.servlet.ServletRequest;
import javax.servlet.jsp.JspException;
import java.util.*;

/**
* Groups a collection of RadioButtonOptions, and handles databinding of their values.
*
* If RadioButtonGroup uses any Format tags, it must have those tags come before above any nested
* RadioButtonOption tags.
* @jsptagref.tagdescription Renders a collection of radiobutton options
* as <input type="radio"> and handles the data binding of their values.
*
* <p>The &lt;netui:radioButtonGroup> tag can generate a set of
* radiobutton options in two ways:
*
* <blockquote>
* <ol>
* <li>they can be dynamically generated by pointing the
* &lt;netui:radioButtonGroup> tag at a {@link java.util.HashMap java.util.HashMap}
* or String[] object</li>
* <li>they can be statically generated by providing a set of children
* {@link RadioButtonOption}
* tags</li>
* </ol>
* </blockquote>
*
* <p><b>Dynamically Generated Radiobutton Options</b>
*
* <p>You can dynamically generate a set of radionbutton options by
* pointing the &lt;netui:radioButtonGroup> tag at a HashMap
* (or any object that implements the {@link java.util.Map java.util.Map} interface).
*
* <p>For example, if you define a HashMap object and get method in the Controller file...
*
* <pre>    public HashMap hashMap = new HashMap();
*
*    protected HashMap getHashMap()
*    {
*        return hashMap;
*    }
*
*    protected void onCreate()
*    {
*        hashMap.put("value1", "Display Text 1");
*        hashMap.put("value2", "Display Text 2");
*        hashMap.put("value3", "Display Text 3");
*    }</pre>
*
* ...point the &lt;netui:radioButtonGroup>
* at the Map object using the <code>optionsDataSource</code> attribute.
*
* <pre>    &lt;netui:radioButtonGroup
*            dataSource="actionForm.selection"
*            optionsDataSource="${pageFlow.hashMap}"></pre>
*
* <p>In the generated radiobutton options, the display text and the
* submitted value can be made to differ.  The HashMap keys will
* form the submitted values, while the HashMap entries will form
* the display texts.
*
* <pre>    &lt;input type="radio" name="wlw-radio_button_group_key:{actionForm.selection}" value="value1">Display Text 1&lt;/input>
*    &lt;input type="radio" name="wlw-radio_button_group_key:{actionForm.selection}" value="value2">Display Text 2&lt;/input>
*    &lt;input type="radio" name="wlw-radio_button_group_key:{actionForm.selection}" value="value3">Display Text 3&lt;/input></pre>
*
* <p>Note that you can point the &lt;netui:radioButtonGroup> tag at a
* String[] object.  A set of radiobutton options will be generated,
* but there will be no difference between the
* display texts and the submitted values.
*
* <p><b>Statically Generated Radiobutton Options</b></p>
*
* <p>To statically generate radiobutton options, place a set of &lt;netui:radioButtonOption> tags inside
* the &lt;netui:radioButtonGroup> tag.
*
* <pre>    &lt;netui:radioButtonGroup dataSource="actionForm.selection">
*        &lt;netui:radioButtonOption value="value1">Display Text 1&lt;/netui:radioButtonOption>&lt;br>
*        &lt;netui:radioButtonOption value="value2">Display Text 2&lt;/netui:radioButtonOption>&lt;br>
*        &lt;netui:radioButtonOption value="value3">Display Text 3&lt;/netui:radioButtonOption>&lt;br>
*    &lt;/netui:radioButtonGroup></pre>
*
* <p><b>Submitting Data</b></p>
*
* <p>A &lt;netui:radioButtonGroup> is submitted as a String value.  Use the <code>dataSource</code> attribute
* to submit to a String object.
*
* <pre>    &lt;netui:radioButtonGroup dataSource="actionForm.selection"></pre>
*
* <p>In this case, the &lt;netui:radioButtonGroup> submits to a String field of a Form Bean.
*
* <pre>    public static class ProcessDataForm extends FormData
*    {
*        private String selection;
*
*        public void setSelection(String selection)
*        {
*            this.selection = selection;
*        }
*
*        public String getSelection()
*        {
*            return this.selection;
*        }
*    }</pre>
* @example In this sample, the &lt;netui:radioButtonGroup>
* submits data to the Form Bean field <code>preferredColors</code>.
*
* <pre>    &lt;netui:radioButtonGroup
*            dataSource="actionForm.preferredColors"
*            optionsDataSource="${pageFlow.colors}" /></pre>
*
* The <code>optionsDataSource</code> attribute points to a get method for a String[] on the Controller file:
*
* <pre>    String[] colors = new String[] {"Red", "Blue", "Green", "Yellow", "White", "Black"};
*
*    public String[] getColors()
*    {
*        return colors;
*    }</pre>
*
* This automatically renders the appropriate set of radionbutton options:
*
* <pre>    &lt;input type="radio" name="wlw-radio_button_group_key:{actionForm.preferredColors}" value="Red">Red&lt;/input>
*    &lt;input type="radio" name="wlw-radio_button_group_key:{actionForm.preferredColors}" value="Blue">Blue&lt;/input>
*    &lt;input type="radio" name="wlw-radio_button_group_key:{actionForm.preferredColors}" value="Green">Green&lt;/input>
*    &lt;input type="radio" name="wlw-radio_button_group_key:{actionForm.preferredColors}" value="Yellow">Yellow&lt;/input>
*    &lt;input type="radio" name="wlw-radio_button_group_key:{actionForm.preferredColors}" value="White">White&lt;/input>
*    &lt;input type="radio" name="wlw-radio_button_group_key:{actionForm.preferredColors}" value="Black">Black&lt;/input></pre>
* @netui:tag name="radioButtonGroup" description="Defines a group of netui:radioButtonOption elements."
*/
public class RadioButtonGroup
        extends HtmlGroupBaseTag
{
    // @todo: selection may not work with options in repeater.
    private static final Logger logger = Logger.getInstance(RadioButtonGroup.class);

    public static final String RADIOBUTTONGROUP_KEY = "radio_button_group_key";

    private String _match;                      // The actual values we will match against, calculated in doStartTag().
    private String _defaultRadio;               //
    private Object _dynamicAttrs;               // The optionsDataSource object
    private InternalStringBuilder _saveBody;            // The body text
    private WriteRenderAppender _writer;


    private static final List _internalNamingChain;

    static
    {
        List l = new ArrayList(3);
        l.add(new FormDataNameInterceptor());
        l.add(new IndexedNameInterceptor());
        l.add(new PrefixNameInterceptor(RADIOBUTTONGROUP_KEY));
        _internalNamingChain = Collections.unmodifiableList(l);
    }

    static
    {
        org.apache.beehive.netui.pageflow.ProcessPopulate.registerPrefixHandler(RADIOBUTTONGROUP_KEY, new RadioButtonGroupPrefixHandler());
    }

    /**
     * The handler for naming and indexing the RadioButtonGroup.
     */
    public static class RadioButtonGroupPrefixHandler
            implements org.apache.beehive.netui.pageflow.RequestParameterHandler
    {
        public void process(javax.servlet.http.HttpServletRequest request, String key,
                            String expr, ProcessPopulate.ExpressionUpdateNode node)
        {
            if (logger.isDebugEnabled()) {
                logger.debug("*********************************************\n" +
                        "process with key \"" + key + "\" and expression \"" + node.expression + "\"" +
                        "*********************************************\n");
            }
        }
    }

    public RadioButtonGroup()
    {
        super();
    }

    /**
     * Return the name of the Tag.
     */
    public String getTagName()
    {
        return "RadioButtonGroup";
    }

    /**
     * Return an <code>ArrayList</code> which represents a chain of <code>INameInterceptor</code>
     * objects.  This method by default returns <code>null</code> and should be overridden
     * by objects that support naming.
     * @return an <code>ArrayList</code> that will contain <code>INameInterceptor</code> objects.
     */
    protected List getNamingChain()
    {
        return _internalNamingChain;
    }

    /**
     * Override the default value to return a string or the empty string if the default value results in a
     * <code>null</code> value.
     * @return the value returned from <code>super.evaluteDefaultValue</code> or the empty string.
     */
    private String evaluateDefaultValue()
    {
        Object val = _defaultValue;

        if (val != null)
            return val.toString();
        return "";
    }

    /**
     * Does the specified value match one of those we are looking for?
     * @param value Value to be compared
     */
    public boolean isMatched(String value, Boolean defaultValue)
    {
        // @todo: there isn't a defaultValue for radio button, what should we do here?
        if (value == null)
            return false;
        if (_match != null)
            return value.equals(_match);
        if (_defaultRadio != null)
            return value.equals(_defaultRadio);

        return false;
    }

    /**
     * Determine the match for the RadioButtonGroup
     * @throws JspException if a JSP exception has occurred
     */
    public int doStartTag()
            throws JspException
    {
        // evaluate the datasource and disabled state.
        Object val = evaluateDataSource();
        if (val != null)
            _match = val.toString();

        // Store this tag itself as a page attribute
        pageContext.setAttribute(RADIOBUTTONGROUP_KEY, this);
        _defaultRadio = evaluateDefaultValue();

        // see if there are errors in the evaluation
        if (hasErrors())
            return SKIP_BODY;

        ServletRequest req = pageContext.getRequest();
        if (_cr == null)
            _cr = TagRenderingBase.Factory.getConstantRendering(req);

        _writer = new WriteRenderAppender(pageContext);
        if (isVertical()) {
            _cr.TABLE(_writer);
        }

        // if this is a repeater then we shouid prime the pump...
        _dynamicAttrs = evaluateOptionsDataSource();
        assert (_dynamicAttrs != null);
        assert (_dynamicAttrs instanceof Map ||
                _dynamicAttrs instanceof Iterator);

        if (_repeater) {
            if (_dynamicAttrs instanceof Map) {
                _dynamicAttrs = ((Map) _dynamicAttrs).entrySet().iterator();

            }
            if (!(_dynamicAttrs instanceof Iterator)) {
                String s = Bundle.getString("Tags_OptionsDSIteratorError");
                registerTagError(s, null);
                return SKIP_BODY;
            }
            while (((Iterator) _dynamicAttrs).hasNext()) {
                _repCurItem = ((Iterator) _dynamicAttrs).next();
                if (_repCurItem != null)
                    break;
            }
            if (isVertical())
                _cr.TR_TD(_writer);

            DataAccessProviderStack.addDataAccessProvider(this, pageContext);
        }
        //write(results.toString());
        // This is basically this is if enough for 5 options
        _saveBody = new InternalStringBuilder(640);
        return EVAL_BODY_INCLUDE;
    }

    /**
     * Save any body content of this tag, which will generally be the
     * option(s) representing the values displayed to the user.
     * @throws JspException if a JSP exception has occurred
     */
    public int doAfterBody() throws JspException
    {
        StringBuilderRenderAppender writer = new StringBuilderRenderAppender(_saveBody);
        if (bodyContent != null) {
            String value = bodyContent.getString();
            bodyContent.clearBody();
            if (value == null)
                value = "";
            _saveBody.append(value);
        }

        if (_repeater) {
            ServletRequest req = pageContext.getRequest();
            if (_cr == null)
                _cr = TagRenderingBase.Factory.getConstantRendering(req);
            if (isVertical())
                _cr.end_TD_TR(writer);

            while (((Iterator) _dynamicAttrs).hasNext()) {
                _repCurItem = ((Iterator) _dynamicAttrs).next();
                if (_repCurItem != null) {
                    _repIdx++;
                    if (isVertical())
                        _cr.TR_TD(writer);
                    return EVAL_BODY_AGAIN;
                }
            }
        }

        return SKIP_BODY;
    }

    /**
     * Render the set of RadioButtonOptions.
     * @throws JspException if a JSP exception has occurred
     */
    public int doEndTag() throws JspException
    {
        if (hasErrors())
            return reportAndExit(EVAL_PAGE);

        String idScript = null;
        String altText = null;
        char accessKey = 0x00;

        // Remove the page scope attributes we created
        pageContext.removeAttribute(RADIOBUTTONGROUP_KEY);
        ServletRequest req = pageContext.getRequest();
        if (_cr == null)
            _cr = TagRenderingBase.Factory.getConstantRendering(req);

        //InternalStringBuilder results = new InternalStringBuilder(128);
        if (_saveBody != null)
            write(_saveBody.toString());

        // if this is a repeater we output the content during the body processing
        if (_repeater) {
            // Render a tag representing the end of our current form
            if (isVertical())
                _cr.end_TABLE(_writer);

            if (idScript != null)
                write(idScript);

            //write(results.toString());
            localRelease();
            return EVAL_PAGE;
        }

        // Render a tag representing the end of our current form
        if (_dynamicAttrs instanceof Map) {
            Map dynamicRadiosMap = (Map) _dynamicAttrs;
            Iterator keyIterator = dynamicRadiosMap.keySet().iterator();
            int idx = 0;
            while (keyIterator.hasNext()) {
                Object optionValue = keyIterator.next();
                String optionDisplay = null;
                if (dynamicRadiosMap.get(optionValue) != null) {
                    optionDisplay = dynamicRadiosMap.get(optionValue).toString();
                }
                else {
                    optionDisplay = "";
                }

                addOption(_writer, INPUT_RADIO, optionValue.toString(), optionDisplay, idx++, altText, accessKey, _disabled);
                if (hasErrors()) {
                    reportErrors();
                    localRelease();
                    return EVAL_PAGE;
                }
                write("\n");

            }
        }
        else {
            assert(_dynamicAttrs instanceof Iterator);

            Iterator it = (Iterator) _dynamicAttrs;
            int idx = 0;
            while (it.hasNext()) {
                Object o = it.next();
                if (o == null)
                    continue;

                if (o instanceof GroupOption) {
                    GroupOption go = (GroupOption) o;
                    addOption(_writer, INPUT_RADIO, go.getValue(), go.getName(), idx++, go.getAlt(), go.getAccessKey(), _disabled);
                }
                else {
                    String radioValue = o.toString();
                    addOption(_writer, INPUT_RADIO, radioValue, radioValue, idx++, altText, accessKey, _disabled);
                }
                if (hasErrors()) {
                    reportErrors();
                    localRelease();
                    return EVAL_PAGE;
                }
                write("\n");
            }
        }

        if (isVertical()) {
            _cr.end_TABLE(_writer);
        }

        if (idScript != null)
            write(idScript);

        //write(results.toString());
        localRelease();
        return EVAL_PAGE;
    }

    /**
     * Release any acquired resources.
     */
    protected void localRelease()
    {
        // remove the context allowing binding to container.item during binding
        if (_repeater)
            DataAccessProviderStack.removeDataAccessProvider(pageContext);

        super.localRelease();

        _match = null;
        _defaultRadio = null;
    }
}
TOP

Related Classes of org.apache.beehive.netui.tags.html.RadioButtonGroup$RadioButtonGroupPrefixHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.