647 lines
24 KiB
Java
647 lines
24 KiB
Java
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The ASF 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.
|
|
*
|
|
* $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.*;
|
|
import org.apache.beehive.netui.util.Bundle;
|
|
import org.apache.beehive.netui.util.iterator.IteratorFactory;
|
|
import org.apache.beehive.netui.util.logging.Logger;
|
|
import org.apache.beehive.netui.util.tags.GroupOption;
|
|
|
|
import javax.servlet.ServletRequest;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.jsp.JspException;
|
|
import java.util.*;
|
|
|
|
/**
|
|
* Groups a collection of CheckBoxOptions, and handles databinding of their values.
|
|
*
|
|
* CheckBoxGroup binds to an Iterator of Strings.
|
|
*
|
|
* If CheckBoxGroup uses any Format tags, it must have those tags come before any nested
|
|
* CheckBoxOption tags.
|
|
* @jsptagref.tagdescription Renders a collection of checkbox options as <input type="checkbox">
|
|
* and handles the data binding.
|
|
*
|
|
* <p><b>Submitting Data</b></p>
|
|
* <p>The <netui:checkBoxGroup> submits data in the form of a String[] object.
|
|
* For example, if the <netui:checkBoxGroup> submits data to a Form Bean field...
|
|
*
|
|
* <pre> <netui:checkBoxGroup
|
|
* dataSource="actionForm.userSelections"
|
|
* optionsDataSource="${pageFlow.availableSelections}" /></pre>
|
|
*
|
|
* ...then the Form Bean field must be a String[] object...
|
|
*
|
|
* <pre> public static class SubmitForm extends FormData
|
|
* {
|
|
* private String[] userSelections;
|
|
*
|
|
* public void setUserSelections(String[] userSelections)
|
|
* {
|
|
* this.userSelections = userSelections;
|
|
* }
|
|
*
|
|
* public String[] getUserSelections()
|
|
* {
|
|
* return this.userSelections;
|
|
* }
|
|
* }</pre>
|
|
*
|
|
* <p><b>Dynamically Defined Checkboxes</b></p>
|
|
* You can dynamically define a set of checkboxes by pointing the <code>optionsDataSource</code> attribute
|
|
* at a String[] object. When the <netui:checkBoxGroup> is rendered in the browser, a
|
|
* corresponding set of
|
|
* checkboxes will be genereated from the String[] object.
|
|
*
|
|
* <p>For example, if you define a String[] object and get method in the Controller file...
|
|
*
|
|
* <pre> public String[] availableSelections = {"option1", "option2", "option3"};
|
|
*
|
|
* public String[] getavailableSelections()
|
|
* {
|
|
* return this.availableSelections;
|
|
* }</pre>
|
|
*
|
|
* ...and reference this String[] from the <code>optionsDataSource</code> attribute...
|
|
*
|
|
* <pre> <netui:checkBoxGroup
|
|
* dataSource="actionForm.userSelections"
|
|
* optionsDataSource="${pageFlow.availableSelections}" /></pre>
|
|
*
|
|
* ...then the appropriate checkboxes will be rendered in the browser.
|
|
*
|
|
* <pre> <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.userSelections}" value="option1">option1</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.userSelections}" value="option2">option2</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.userSelections}" value="option3">option3</input></pre>
|
|
*
|
|
* For checkboxes to be rendered, either the <code>optionsDataSource</code> attribute must be provided
|
|
* (and point to a String[] object) or the <netui:checkBoxGroup> must have children
|
|
* <netuiCheckBoxOption> tags.
|
|
*
|
|
* <p><b>Setting Default Options</b></p>
|
|
* <p>The <code>defaultValue</code> attribute can be used to determine which checkboxs are checked
|
|
* when they are first rendered in the browser. The <code>defaultValue</code> attribute
|
|
* should point to a String, if only one checkbox should appear checked, or to a String[] object,
|
|
* if multiple checkboxes should appear checked.
|
|
* @example In this first sample, the <netui:checkBoxGroup>
|
|
* submits data to the Form Bean field <code>preferredColors</code>.
|
|
*
|
|
* <pre> <netui:checkBoxGroup
|
|
* 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 checkbox options within the <checkBoxGroup>:
|
|
*
|
|
* <pre> <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Red">Red</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Blue">Blue</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Green">Green</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Yellow">Yellow</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="White">White</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Black">Black</input></pre>
|
|
*
|
|
* The <code>defaultValue</code> attribute may point to a String or a String[].
|
|
*
|
|
* <pre> <netui:checkBoxGroup
|
|
* dataSource="actionForm.preferredColors"
|
|
* optionsDataSource="${pageFlow.colors}"
|
|
* defaultValue="${pageFlow.defaultColor}" /></pre>
|
|
*
|
|
* And in the Controller:
|
|
* <pre> String defaultColor = new String ("Blue");
|
|
* ...</pre>
|
|
* or
|
|
* <pre> String[] defaultColor = new String[] {"Red", "Blue"};
|
|
* ...</pre>
|
|
*
|
|
* In either case, the appropriate
|
|
* checkbox options will appear checked in the browser.
|
|
*
|
|
* <pre> <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Red" checked="true">Red</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Blue" checked="true">Blue</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Green">Green</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Yellow">Yellow</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="White">White</input>
|
|
* <input type="checkbox" name="wlw-checkbox_group_key:{actionForm.preferredColors}" value="Black">Black</input></pre>
|
|
* @netui:tag name="checkBoxGroup" description="Groups a collection of CheckBoxOptions, and handles databinding of their values."
|
|
*/
|
|
public class CheckBoxGroup
|
|
extends HtmlGroupBaseTag
|
|
{
|
|
// @todo: seems like we should write out the hidden field even if the option is disabled.
|
|
private static final Logger logger = Logger.getInstance(CheckBoxGroup.class);
|
|
|
|
/**
|
|
* This is the name of the prefixHandler for the checkbox grup.
|
|
*/
|
|
public static final String CHECKBOXGROUP_KEY = "checkbox_group_key";
|
|
|
|
private static final String OLDVALUE_SUFFIX = "OldValue";
|
|
|
|
private InputHiddenTag.State _state = new InputHiddenTag.State();
|
|
private InputHiddenTag.State _hiddenState = new InputHiddenTag.State();
|
|
|
|
private List _defaultSelections;
|
|
private boolean _defaultSingleton = false;
|
|
private boolean _defaultSingleValue = false;
|
|
|
|
private String[] _match; // The actual values we will match against, calculated in doStartTag().
|
|
private Object _dynamicAttrs; // the Object
|
|
private InternalStringBuilder _saveBody;
|
|
|
|
private static final List _internalNamingChain;
|
|
private WriteRenderAppender _writer;
|
|
|
|
static
|
|
{
|
|
List l = new ArrayList(3);
|
|
l.add(new FormDataNameInterceptor());
|
|
l.add(new IndexedNameInterceptor());
|
|
l.add(new PrefixNameInterceptor(CHECKBOXGROUP_KEY));
|
|
_internalNamingChain = Collections.unmodifiableList(l);
|
|
}
|
|
|
|
static
|
|
{
|
|
org.apache.beehive.netui.pageflow.ProcessPopulate.registerPrefixHandler(CHECKBOXGROUP_KEY, new CheckboxGroupPrefixHandler());
|
|
}
|
|
|
|
/**
|
|
* The handler for naming and indexing the CheckBoxGroup.
|
|
*/
|
|
public static class CheckboxGroupPrefixHandler
|
|
implements org.apache.beehive.netui.pageflow.RequestParameterHandler
|
|
{
|
|
/**
|
|
* Determines the current state of the CheckBoxGroup based on the Request.
|
|
*/
|
|
public void process(HttpServletRequest request, String key, String expr,
|
|
ProcessPopulate.ExpressionUpdateNode node)
|
|
{
|
|
String[] returnArray = null;
|
|
|
|
if (!key.endsWith(OLDVALUE_SUFFIX)) {
|
|
//This select has values and should stay that way
|
|
returnArray = request.getParameterValues(key);
|
|
}
|
|
else {
|
|
//Check the request to see if select also exists
|
|
String newKey = key.substring(0, key.indexOf(OLDVALUE_SUFFIX));
|
|
String[] select = request.getParameterValues(newKey);
|
|
if (select != null) {
|
|
returnArray = select;
|
|
}
|
|
else {
|
|
returnArray = new String[0]; //null;
|
|
}
|
|
}
|
|
|
|
if (node.expression.endsWith(OLDVALUE_SUFFIX)) {
|
|
node.expression = node.expression.substring(0, node.expression.indexOf(OLDVALUE_SUFFIX));
|
|
}
|
|
node.values = returnArray;
|
|
|
|
if (logger.isDebugEnabled()) {
|
|
logger.debug("\n*********************************************\n" +
|
|
"process with key \"" + key + "\" and expression \"" + node.expression + "\"" + "and result size: "
|
|
+ (returnArray != null ? "" + returnArray.length : null) + "\n" +
|
|
"*********************************************\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
public CheckBoxGroup()
|
|
{
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* Return the name of the Tag.
|
|
*/
|
|
public String getTagName()
|
|
{
|
|
return "CheckBoxGroup";
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* Overrided method to return a list of the possible default values. The method always return either
|
|
* a <code>List</code> or null.
|
|
* @return a <code>List</code> that represents the default value.
|
|
*/
|
|
private Object evaluateDefaultValue()
|
|
{
|
|
Object val = _defaultValue;
|
|
|
|
List defaults = null;
|
|
if (val instanceof String) {
|
|
if ("checked".equals(val)) {
|
|
_defaultSingleton = true;
|
|
_defaultSingleValue = true;
|
|
return null;
|
|
}
|
|
else if ("unchecked".equals(val)) {
|
|
_defaultSingleton = true;
|
|
_defaultSingleValue = false;
|
|
return null;
|
|
}
|
|
|
|
defaults = new ArrayList();
|
|
defaults.add(val);
|
|
return defaults;
|
|
}
|
|
|
|
Iterator optionsIterator = null;
|
|
optionsIterator = IteratorFactory.createIterator(val);
|
|
|
|
// log an error, default value is optional so only warn
|
|
if (optionsIterator == null && _defaultValue != null) {
|
|
logger.warn(Bundle.getString("Tags_IteratorError",
|
|
new Object[]{getTagName(), "defaultValue", _defaultValue}));
|
|
}
|
|
if (optionsIterator == null)
|
|
optionsIterator = IteratorFactory.EMPTY_ITERATOR;
|
|
|
|
defaults = new ArrayList();
|
|
while (optionsIterator.hasNext()) {
|
|
defaults.add(optionsIterator.next());
|
|
}
|
|
|
|
return defaults;
|
|
}
|
|
|
|
/**
|
|
* Checks whether the given value matches one of the CheckBoxGroup's selected
|
|
* CheckBoxOptions.
|
|
* @param value Value to be compared
|
|
*/
|
|
public boolean isMatched(String value, Boolean defaultValue)
|
|
{
|
|
if (value == null)
|
|
return false;
|
|
|
|
if (_match != null) {
|
|
for (int i = 0; i < _match.length; i++) {
|
|
if (value.equals(_match[i]))
|
|
return true;
|
|
}
|
|
}
|
|
else {
|
|
// a provided default value will override the group
|
|
if (defaultValue != null)
|
|
return defaultValue.booleanValue();
|
|
|
|
// if we have a singleton definition then use that
|
|
if (_defaultSingleton)
|
|
return _defaultSingleValue;
|
|
|
|
// check to see if we have a default arraylist with the value in it
|
|
if (_defaultSelections != null)
|
|
return _defaultSelections.contains(value);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Determine the set of matches for the CheckBoxGroup
|
|
* @throws JspException if a JSP exception has occurred
|
|
*/
|
|
public int doStartTag() throws JspException
|
|
{
|
|
ServletRequest req = pageContext.getRequest();
|
|
if (_cr == null)
|
|
_cr = TagRenderingBase.Factory.getConstantRendering(req);
|
|
|
|
// get the evaluated dataSource and default values
|
|
Object val = evaluateDataSource();
|
|
_defaultSelections = (List) evaluateDefaultValue();
|
|
if (hasErrors()) {
|
|
return SKIP_BODY;
|
|
}
|
|
|
|
// process the default values and create the matching array...
|
|
if (val != null) {
|
|
buildMatch(val);
|
|
if (hasErrors()) {
|
|
return SKIP_BODY;
|
|
}
|
|
}
|
|
|
|
// if the checkbox group is disabled do not write out the
|
|
// hidden field.
|
|
_writer = new WriteRenderAppender(pageContext);
|
|
if (!_repeater && !_disabled) {
|
|
|
|
//Create hidden field for state tracking
|
|
_state.clear();
|
|
String hiddenParamName = null;
|
|
hiddenParamName = getQualifiedDataSourceName() + OLDVALUE_SUFFIX;
|
|
_state.name = hiddenParamName;
|
|
_state.value = "true";
|
|
|
|
TagRenderingBase hiddenTag = TagRenderingBase.Factory.getRendering(TagRenderingBase.INPUT_HIDDEN_TAG, req);
|
|
hiddenTag.doStartTag(_writer, _state);
|
|
hiddenTag.doEndTag(_writer);
|
|
}
|
|
|
|
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);
|
|
}
|
|
_saveBody = new InternalStringBuilder(128);
|
|
|
|
// Continue processing this page
|
|
return EVAL_BODY_BUFFERED;
|
|
|
|
}
|
|
|
|
/**
|
|
* 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 CheckBoxOptions.
|
|
* @throws JspException if a JSP exception has occurred
|
|
*/
|
|
public int doEndTag()
|
|
throws JspException
|
|
{
|
|
if (hasErrors())
|
|
return reportAndExit(EVAL_PAGE);
|
|
|
|
ServletRequest req = pageContext.getRequest();
|
|
if (_cr == null)
|
|
_cr = TagRenderingBase.Factory.getConstantRendering(req);
|
|
|
|
String idScript = null;
|
|
String altText = null;
|
|
char accessKey = 0x00;
|
|
|
|
|
|
// Render a tag representing the end of our current form
|
|
if (_saveBody != null)
|
|
write(_saveBody.toString());
|
|
|
|
// if this is a repeater then we have created the content in the body so we write that
|
|
if (_repeater) {
|
|
// Render a tag representing the end of our current form
|
|
if (isVertical())
|
|
_cr.end_TABLE(_writer);
|
|
|
|
if (idScript != null)
|
|
write(idScript);
|
|
|
|
localRelease();
|
|
return EVAL_PAGE;
|
|
}
|
|
|
|
// non repeater working against the options data source
|
|
assert(_dynamicAttrs != null);
|
|
if (_dynamicAttrs instanceof Map) {
|
|
Map dynamicCheckboxesMap = (Map) _dynamicAttrs;
|
|
Iterator keyIterator = dynamicCheckboxesMap.keySet().iterator();
|
|
int idx = 0;
|
|
while (keyIterator.hasNext()) {
|
|
Object optionValue = keyIterator.next();
|
|
String optionDisplay = "";
|
|
if (dynamicCheckboxesMap.get(optionValue) != null)
|
|
optionDisplay = dynamicCheckboxesMap.get(optionValue).toString();
|
|
if (optionValue != null) {
|
|
addOption(_writer, INPUT_CHECKBOX, optionValue.toString(), optionDisplay, idx++, altText, accessKey, _disabled);
|
|
}
|
|
|
|
if (hasErrors()) {
|
|
reportErrors();
|
|
if (isVertical()) {
|
|
_cr.end_TABLE(_writer);
|
|
}
|
|
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_CHECKBOX, go.getValue(), go.getName(), idx++, go.getAlt(), go.getAccessKey(), _disabled);
|
|
}
|
|
else {
|
|
String checkboxValue = o.toString();
|
|
addOption(_writer, INPUT_CHECKBOX, checkboxValue, checkboxValue, idx++, altText, accessKey, _disabled);
|
|
}
|
|
|
|
if (hasErrors()) {
|
|
reportErrors();
|
|
if (isVertical()) {
|
|
_cr.end_TABLE(_writer);
|
|
}
|
|
localRelease();
|
|
return EVAL_PAGE;
|
|
}
|
|
write("\n");
|
|
}
|
|
}
|
|
|
|
if (isVertical())
|
|
_cr.end_TABLE(_writer);
|
|
|
|
if (idScript != null)
|
|
write(idScript);
|
|
|
|
localRelease();
|
|
return EVAL_PAGE;
|
|
}
|
|
|
|
public void createHiddenField(AbstractRenderAppender results)
|
|
throws JspException
|
|
{
|
|
if (_repIdx == 0 && !_disabled) {
|
|
|
|
ServletRequest req = pageContext.getRequest();
|
|
|
|
//Create hidden field for state tracking
|
|
String hiddenParamName = null;
|
|
hiddenParamName = getQualifiedDataSourceName() + OLDVALUE_SUFFIX;
|
|
_hiddenState.name = hiddenParamName;
|
|
_hiddenState.value = "true";
|
|
|
|
TagRenderingBase hiddenTag = TagRenderingBase.Factory.getRendering(TagRenderingBase.INPUT_HIDDEN_TAG, req);
|
|
hiddenTag.doStartTag(results, _hiddenState);
|
|
hiddenTag.doEndTag(results);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Release any acquired resources.
|
|
*/
|
|
protected void localRelease()
|
|
{
|
|
// cleanup the context variables used for binding during repeater
|
|
if (_repeater)
|
|
DataAccessProviderStack.removeDataAccessProvider(pageContext);
|
|
|
|
super.localRelease();
|
|
|
|
_defaultSelections = null;
|
|
_match = null;
|
|
_dynamicAttrs = null;
|
|
_saveBody = null;
|
|
_defaultSingleton = false;
|
|
_defaultSingleValue = false;
|
|
_writer = null;
|
|
|
|
_state.clear();
|
|
_hiddenState.clear();
|
|
}
|
|
|
|
// This method will build the match list, should this be a hashmap?
|
|
private void buildMatch(Object val)
|
|
{
|
|
if (val instanceof String[]) {
|
|
_match = (String[]) val;
|
|
}
|
|
else {
|
|
Iterator matchIterator = null;
|
|
// this should return null, but we should handle it it does
|
|
matchIterator = IteratorFactory.createIterator(val);
|
|
if (matchIterator == null)
|
|
matchIterator = IteratorFactory.EMPTY_ITERATOR;
|
|
|
|
List matchList = new ArrayList();
|
|
while (matchIterator.hasNext()) {
|
|
Object o = matchIterator.next();
|
|
if (o != null)
|
|
matchList.add(o.toString());
|
|
}
|
|
int size = matchList.size();
|
|
|
|
_match = new String[size];
|
|
for (int i = 0; i < size; i++) {
|
|
_match[i] = matchList.get(i).toString();
|
|
}
|
|
}
|
|
|
|
if (logger.isDebugEnabled()) {
|
|
logger.debug("****** CheckboxGroup Matches ******");
|
|
if (_match != null) {
|
|
for (int i = 0; i < _match.length; i++) {
|
|
logger.debug(i + ": " + _match[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|