You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mb...@apache.org on 2005/09/02 14:49:26 UTC
svn commit: r267196 - in /myfaces:
api/trunk/src/java/javax/faces/component/UISelectOne.java
share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java
share/trunk/src/java/org/apache/myfaces/util/SelectItemsIterator.java
Author: mbr
Date: Fri Sep 2 05:49:18 2005
New Revision: 267196
URL: http://svn.apache.org/viewcvs?rev=267196&view=rev
Log:
fix for MYFACES-465
Added:
myfaces/share/trunk/src/java/org/apache/myfaces/util/SelectItemsIterator.java
Modified:
myfaces/api/trunk/src/java/javax/faces/component/UISelectOne.java
myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java
Modified: myfaces/api/trunk/src/java/javax/faces/component/UISelectOne.java
URL: http://svn.apache.org/viewcvs/myfaces/api/trunk/src/java/javax/faces/component/UISelectOne.java?rev=267196&r1=267195&r2=267196&view=diff
==============================================================================
--- myfaces/api/trunk/src/java/javax/faces/component/UISelectOne.java (original)
+++ myfaces/api/trunk/src/java/javax/faces/component/UISelectOne.java Fri Sep 2 05:49:18 2005
@@ -15,8 +15,14 @@
*/
package javax.faces.component;
+import java.util.Arrays;
+import java.util.Iterator;
+
import javax.faces.context.FacesContext;
+import javax.faces.model.SelectItem;
+import javax.faces.model.SelectItemGroup;
+import org.apache.myfaces.util.SelectItemsIterator;
/**
* see Javadoc of JSF Specification
@@ -24,18 +30,62 @@
* @author Manfred Geiler (latest modification by $Author$)
* @version $Revision$ $Date$
*/
-public class UISelectOne
- extends UIInput
+public class UISelectOne extends UIInput
{
public static final String INVALID_MESSAGE_ID = "javax.faces.component.UISelectOne.INVALID";
- public void validate(FacesContext context)
+ /**
+ * @see javax.faces.component.UIInput#validateValue(javax.faces.context.FacesContext, java.lang.Object)
+ */
+ protected void validateValue(FacesContext context, Object value)
{
- super.validate(context);
- //TODO: see javadoc: iterate through UISelectItem and UISelectItems and check
- //current value against these items
+ super.validateValue(context, value);
+
+ if (!isValid() || value == null)
+ {
+ return;
+ }
+
+ // selected value must match to one of the available options
+ if (!matchValue(context, value, new SelectItemsIterator(this)))
+ {
+ _MessageUtils.addErrorMessage(context, this, INVALID_MESSAGE_ID,
+ new Object[] {getId()});
+ setValid(false);
+ }
}
+ /**
+ * @param context
+ * @param value
+ * @param iterator
+ * @return
+ */
+ private boolean matchValue(FacesContext context, Object value,
+ Iterator selectItemsIter)
+ {
+ while (selectItemsIter.hasNext())
+ {
+ SelectItem item = (SelectItem) selectItemsIter.next();
+ if (value.equals(item.getValue()))
+ {
+ return true;
+ }
+ if (item instanceof SelectItemGroup)
+ {
+ SelectItemGroup itemgroup = (SelectItemGroup) item;
+ SelectItem[] selectItems = itemgroup.getSelectItems();
+ if (selectItems != null
+ && selectItems.length > 0
+ && matchValue(context, value, Arrays.asList(
+ selectItems).iterator()))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
//------------------ GENERATED CODE BEGIN (do not modify!) --------------------
@@ -43,7 +93,6 @@
public static final String COMPONENT_FAMILY = "javax.faces.SelectOne";
private static final String DEFAULT_RENDERER_TYPE = "javax.faces.Menu";
-
public UISelectOne()
{
setRendererType(DEFAULT_RENDERER_TYPE);
@@ -53,7 +102,6 @@
{
return COMPONENT_FAMILY;
}
-
//------------------ GENERATED CODE END ---------------------------------------
}
Modified: myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java
URL: http://svn.apache.org/viewcvs/myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java?rev=267196&r1=267195&r2=267196&view=diff
==============================================================================
--- myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java (original)
+++ myfaces/share/trunk/src/java/org/apache/myfaces/renderkit/RendererUtils.java Fri Sep 2 05:49:18 2005
@@ -52,6 +52,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.util.HashMapUtils;
+import org.apache.myfaces.util.SelectItemsIterator;
/**
* @author Manfred Geiler (latest modification by $Author$)
@@ -478,95 +479,13 @@
return list;
}
*/
-
- List list = new ArrayList(uiComponent.getChildCount());
- for (Iterator children = uiComponent.getChildren().iterator(); children.hasNext(); )
+
+ List list = new ArrayList();
+
+ for (Iterator iter = new SelectItemsIterator(uiComponent); iter.hasNext();)
{
- UIComponent child = (UIComponent)children.next();
- if (child instanceof UISelectItem)
- {
- Object value = ((UISelectItem) child).getValue();
- if (value != null)
- {
- //get SelectItem from model via value binding
- if (!(value instanceof SelectItem))
- {
- ValueBinding binding = ((UISelectItem) child).getValueBinding("value");
- throw new IllegalArgumentException("Value binding '"+(binding==null?null:binding.getExpressionString())
- +"' of UISelectItem : " + getPathToComponent(child) + " does not reference an Object of type SelectItem");
- }
- list.add(value);
- }
- else
- {
- Object itemValue = ((UISelectItem)child).getItemValue();
- String label = ((UISelectItem)child).getItemLabel();
- String description = ((UISelectItem)child).getItemDescription();
- boolean disabled = ((UISelectItem)child).isItemDisabled();
- if (label == null)
- {
- list.add(new SelectItem(itemValue, itemValue.toString(), description, disabled));
- }
- else
- {
- list.add(new SelectItem(itemValue, label, description, disabled));
- }
- }
- }
- else if (child instanceof UISelectItems)
- {
- UISelectItems items = ((UISelectItems) child);
-
- Object value = items.getValue(); // TODO : Check here for getSubmittedValue.
-
- if (value instanceof SelectItem)
- {
- list.add(value);
- }
- else if (value instanceof SelectItem[])
- {
- for (int i = 0; i < ((SelectItem[])value).length; i++)
- {
- list.add(((SelectItem[])value)[i]);
- }
- }
- else if (value instanceof Collection)
- {
- for (Iterator it = ((Collection)value).iterator(); it.hasNext();)
- {
- Object item = it.next();
- if (!(item instanceof SelectItem))
- {
- ValueBinding binding = items.getValueBinding("value");
- throw new IllegalArgumentException("Collection referenced by UISelectItems with binding '"+
- binding.getExpressionString()+"' and Component-Path : " + getPathToComponent(child) + " does not contain Objects of type SelectItem");
- }
- list.add(item);
- }
- }
- else if (value instanceof Map)
- {
- for (Iterator it = ((Map)value).entrySet().iterator(); it.hasNext();)
- {
- Map.Entry entry = (Map.Entry)it.next();
- list.add(new SelectItem(entry.getValue(), entry.getKey().toString()));
- }
- }
- else
- {
- ValueBinding binding = items.getValueBinding("value");
-
- throw new IllegalArgumentException("Value binding '"+
- (binding==null?null:binding.getExpressionString())+"'of UISelectItems with component-path " + getPathToComponent(child) + " does not reference an Object of type SelectItem, SelectItem[], Collection or Map but of type : "+((value==null)?null:value.getClass().getName()));
- }
- }
- else
- {
- //todo: may other objects than selectItems be nested or not?
- //log.error("Invalid component : " + getPathToComponent(child) + " : must be UISelectItem or UISelectItems, is of type : "+((child==null)?"null":child.getClass().getName()));
- }
- }
-
+ list.add(iter.next());
+ }
return list;
}
Added: myfaces/share/trunk/src/java/org/apache/myfaces/util/SelectItemsIterator.java
URL: http://svn.apache.org/viewcvs/myfaces/share/trunk/src/java/org/apache/myfaces/util/SelectItemsIterator.java?rev=267196&view=auto
==============================================================================
--- myfaces/share/trunk/src/java/org/apache/myfaces/util/SelectItemsIterator.java (added)
+++ myfaces/share/trunk/src/java/org/apache/myfaces/util/SelectItemsIterator.java Fri Sep 2 05:49:18 2005
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2005 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.
+ */
+package org.apache.myfaces.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UISelectItem;
+import javax.faces.component.UISelectItems;
+import javax.faces.el.ValueBinding;
+import javax.faces.model.SelectItem;
+
+import org.apache.myfaces.renderkit.RendererUtils;
+
+/**
+ * @author Mathias Broekelmann (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class SelectItemsIterator implements Iterator
+{
+ private final Iterator _childs;
+ private Iterator _nestedItems;
+ private UISelectItems _currentUISelectItems;
+ private String _collectionLabel;
+
+ public SelectItemsIterator(UIComponent selectItemsParent)
+ {
+ _childs = selectItemsParent.getChildren().iterator();
+ }
+
+ public boolean hasNext()
+ {
+ if (_nestedItems != null)
+ {
+ if (_nestedItems.hasNext())
+ {
+ return true;
+ }
+ _nestedItems = null;
+ _currentUISelectItems = null;
+ }
+ return _childs.hasNext();
+ }
+
+ public Object next()
+ {
+ if (!hasNext())
+ {
+ throw new NoSuchElementException();
+ }
+ if (_nestedItems != null)
+ {
+ Object item = _nestedItems.next();
+ if (!(item instanceof SelectItem))
+ {
+ ValueBinding binding = _currentUISelectItems
+ .getValueBinding("value");
+ throw new IllegalArgumentException(
+ _collectionLabel + " referenced by UISelectItems with binding '"
+ + binding.getExpressionString()
+ + "' and Component-Path : " + RendererUtils.getPathToComponent(_currentUISelectItems)
+ + " does not contain Objects of type SelectItem");
+ }
+ return _nestedItems.next();
+ }
+ else if (_childs.hasNext())
+ {
+ UIComponent child = (UIComponent) _childs.next();
+ if (child instanceof UISelectItem)
+ {
+ UISelectItem uiSelectItem = (UISelectItem) child;
+ Object item = uiSelectItem.getValue();
+ if (item == null)
+ {
+ Object itemValue = ((UISelectItem) child).getItemValue();
+ String label = ((UISelectItem) child).getItemLabel();
+ String description = ((UISelectItem) child)
+ .getItemDescription();
+ boolean disabled = ((UISelectItem) child).isItemDisabled();
+ if (label == null)
+ {
+ return new SelectItem(itemValue, itemValue.toString(),
+ description, disabled);
+ }
+ return new SelectItem(itemValue, label, description,
+ disabled);
+ }
+ else if (!(item instanceof SelectItem))
+ {
+ ValueBinding binding = ((UISelectItem) child)
+ .getValueBinding("value");
+ throw new IllegalArgumentException(
+ "Value binding '"
+ + (binding == null ? null : binding.getExpressionString())
+ + "' of UISelectItem : "
+ + RendererUtils.getPathToComponent(child)
+ + " does not reference an Object of type SelectItem");
+ }
+ return item;
+ }
+ else if (child instanceof UISelectItems)
+ {
+ _currentUISelectItems = ((UISelectItems) child);
+
+ Object value = _currentUISelectItems.getValue();
+
+ if (value instanceof SelectItem)
+ {
+ return value;
+ }
+ else if (value instanceof SelectItem[])
+ {
+ _nestedItems = Arrays.asList((SelectItem[]) value)
+ .iterator();
+ _collectionLabel = "Array";
+ return next();
+ }
+ else if (value instanceof Collection)
+ {
+ _nestedItems = ((Collection)value).iterator();
+ _collectionLabel = "Collection";
+ return next();
+ }
+ else if (value instanceof Map)
+ {
+ Map map = ((Map) value);
+ Collection items = new ArrayList(map.size());
+ for (Iterator it = map.entrySet().iterator(); it
+ .hasNext();)
+ {
+ Map.Entry entry = (Map.Entry) it.next();
+ items.add(new SelectItem(entry.getValue(), entry
+ .getKey().toString()));
+ }
+ _nestedItems = items.iterator();
+ _collectionLabel = null;
+ return next();
+ }
+ else
+ {
+ ValueBinding binding = _currentUISelectItems.getValueBinding("value");
+
+ throw new IllegalArgumentException(
+ "Value binding '"
+ + (binding == null ? null : binding
+ .getExpressionString())
+ + "'of UISelectItems with component-path "
+ + RendererUtils.getPathToComponent(child)
+ + " does not reference an Object of type SelectItem, SelectItem[], Collection or Map but of type : "
+ + ((value == null) ? null : value
+ .getClass()
+ .getName()));
+ }
+ }
+ else
+ {
+ //todo: may other objects than selectItems be nested or not?
+ //log.error("Invalid component : " + getPathToComponent(child) + " : must be UISelectItem or UISelectItems, is of type : "+((child==null)?"null":child.getClass().getName()));
+ }
+ }
+ return null;
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}