You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ma...@apache.org on 2010/11/04 15:39:50 UTC
svn commit: r1031006 - in /myfaces/core/trunk/api/src:
main/java/javax/faces/component/ test/java/javax/faces/component/
Author: martinkoci
Date: Thu Nov 4 14:39:49 2010
New Revision: 1031006
URL: http://svn.apache.org/viewvc?rev=1031006&view=rev
Log:
MYFACES-2920: UISelectOne/UISelectMany validateValue: Before comparing each option, coerce the option value type to the type of component's value
https://issues.apache.org/jira/browse/MYFACES-2920
Added:
myfaces/core/trunk/api/src/test/java/javax/faces/component/_SelectItemsUtilTest.java
Modified:
myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectMany.java
myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectOne.java
myfaces/core/trunk/api/src/main/java/javax/faces/component/_SelectItemsUtil.java
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectMany.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectMany.java?rev=1031006&r1=1031005&r2=1031006&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectMany.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectMany.java Thu Nov 4 14:39:49 2010
@@ -28,6 +28,7 @@ import java.util.Iterator;
import javax.el.ValueExpression;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.el.ValueBinding;
import javax.faces.model.SelectItem;
@@ -350,39 +351,22 @@ public class UISelectMany extends UIInpu
{
// all selected values must match to the values of the available options
- _SelectItemsUtil._ValueConverter converter = new _SelectItemsUtil._ValueConverter()
- {
- public Object getConvertedValue(FacesContext context, String value)
- {
- Object convertedValue = UISelectMany.this.getConvertedValue(context, new String[] { value });
- if (convertedValue instanceof Collection)
- {
- Iterator<?> iter = ((Collection<?>) convertedValue).iterator();
- if (iter.hasNext())
- {
- return iter.next();
- }
- return null;
- }
- return ((Object[]) convertedValue)[0];
- }
- };
-
Collection<SelectItem> items = new ArrayList<SelectItem>();
for (Iterator<SelectItem> iter = new _SelectItemsIterator(this, context); iter.hasNext();)
{
items.add(iter.next());
}
+ Converter converter = getConverter();
while (itemValues.hasNext())
{
Object itemValue = itemValues.next();
// selected value must match to one of the available options
// and if required is true it must not match an option with noSelectionOption set to true (since 2.0)
- if (!_SelectItemsUtil.matchValue(context, itemValue, items.iterator(), converter)
+ if (!_SelectItemsUtil.matchValue(context, this, itemValue, items.iterator(), converter)
|| (
this.isRequired()
- && _SelectItemsUtil.isNoSelectionOption(context, itemValue, items.iterator(), converter)
+ && _SelectItemsUtil.isNoSelectionOption(context, this, itemValue, items.iterator(), converter)
))
{
_MessageUtils.addErrorMessage(context, this, INVALID_MESSAGE_ID,
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectOne.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectOne.java?rev=1031006&r1=1031005&r2=1031006&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectOne.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UISelectOne.java Thu Nov 4 14:39:49 2010
@@ -19,10 +19,10 @@
package javax.faces.component;
import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
-import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
/**
* Component for choosing one option out of a set of possibilities.
@@ -71,20 +71,13 @@ public class UISelectOne extends UIInput
return;
}
- _SelectItemsUtil._ValueConverter converter = new _SelectItemsUtil._ValueConverter()
- {
- public Object getConvertedValue(FacesContext context, String value)
- {
- return UISelectOne.this.getConvertedValue(context, value);
- }
- };
-
// selected value must match to one of the available options
// and if required is true it must not match an option with noSelectionOption set to true (since 2.0)
- if (!(_SelectItemsUtil.matchValue(context, value, new _SelectItemsIterator(this, context), converter)
+ Converter converter = getConverter();
+ if (!(_SelectItemsUtil.matchValue(context, this, value, new _SelectItemsIterator(this, context), converter)
&& (!this.isRequired()
|| (this.isRequired()
- && !_SelectItemsUtil.isNoSelectionOption(context, value, new _SelectItemsIterator(this, context), converter)))))
+ && !_SelectItemsUtil.isNoSelectionOption(context, this, value, new _SelectItemsIterator(this, context), converter)))))
{
_MessageUtils.addErrorMessage(context, this, INVALID_MESSAGE_ID, new Object[] { _MessageUtils.getLabel(
context, this) });
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/_SelectItemsUtil.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/_SelectItemsUtil.java?rev=1031006&r1=1031005&r2=1031006&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/_SelectItemsUtil.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/_SelectItemsUtil.java Thu Nov 4 14:39:49 2010
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Iterator;
import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import javax.faces.model.SelectItemGroup;
@@ -31,20 +32,18 @@ import javax.faces.model.SelectItemGroup
*/
class _SelectItemsUtil
{
- static interface _ValueConverter
- {
- Object getConvertedValue(FacesContext context, String value);
- }
-
+
/**
* @param context the faces context
+ * @param uiComponent the component instance
* @param value the value to check
- * @param converter
+ * @param converter a converter instance
* @param iterator contains instances of SelectItem
* @return if the value of a selectitem is equal to the given value
*/
- public static boolean matchValue(FacesContext context, Object value,
- Iterator<SelectItem> selectItemsIter, _ValueConverter converter)
+ public static boolean matchValue(FacesContext context,
+ UIComponent uiComponent, Object value,
+ Iterator<SelectItem> selectItemsIter, Converter converter)
{
while (selectItemsIter.hasNext())
{
@@ -54,38 +53,37 @@ class _SelectItemsUtil
SelectItemGroup itemgroup = (SelectItemGroup) item;
SelectItem[] selectItems = itemgroup.getSelectItems();
if (selectItems != null
- && selectItems.length > 0
- && matchValue(context, value, Arrays.asList(
- selectItems).iterator(), converter))
+ && selectItems.length > 0
+ && matchValue(context, uiComponent, value, Arrays
+ .asList(selectItems).iterator(), converter))
{
return true;
}
}
else
{
- Object itemValue = item.getValue();
- if(converter != null && itemValue instanceof String)
- {
- itemValue = converter.getConvertedValue(context, (String)itemValue);
- }
- if (value==itemValue || value.equals(itemValue))
+ Object itemValue = _convertOrCoerceValue(context,
+ uiComponent, value, item, converter);
+ if (value == itemValue || value.equals(itemValue))
{
return true;
}
}
}
return false;
- }
-
+ }
+
/**
* @param context the faces context
+ * @param uiComponent the component instance
* @param value the value to check
* @param converter
* @param iterator contains instances of SelectItem
* @return if the value is a SelectItem of selectItemsIter, on which noSelectionOption is true
*/
- public static boolean isNoSelectionOption(FacesContext context, Object value,
- Iterator<SelectItem> selectItemsIter, _ValueConverter converter)
+ public static boolean isNoSelectionOption(FacesContext context,
+ UIComponent uiComponent, Object value,
+ Iterator<SelectItem> selectItemsIter, Converter converter)
{
while (selectItemsIter.hasNext())
{
@@ -95,26 +93,46 @@ class _SelectItemsUtil
SelectItemGroup itemgroup = (SelectItemGroup) item;
SelectItem[] selectItems = itemgroup.getSelectItems();
if (selectItems != null
- && selectItems.length > 0
- && isNoSelectionOption(context, value, Arrays.asList(
- selectItems).iterator(), converter))
+ && selectItems.length > 0
+ && isNoSelectionOption(context, uiComponent, value,
+ Arrays.asList(selectItems).iterator(),
+ converter))
{
return true;
}
}
- else if(item.isNoSelectionOption())
+ else if (item.isNoSelectionOption())
{
- Object itemValue = item.getValue();
- if(converter != null && itemValue instanceof String)
- {
- itemValue = converter.getConvertedValue(context, (String)itemValue);
- }
- if (value==itemValue || value.equals(itemValue))
+ Object itemValue = _convertOrCoerceValue(context, uiComponent,
+ value, item, converter);
+ if (value == itemValue || value.equals(itemValue))
{
return true;
}
}
}
return false;
+ }
+
+ /**
+ * If converter is available and selectItem.value is String uses getAsObject,
+ * otherwise uses EL type coertion and return result.
+ */
+ private static Object _convertOrCoerceValue(FacesContext facesContext,
+ UIComponent uiComponent, Object value, SelectItem selectItem,
+ Converter converter)
+ {
+ Object itemValue = selectItem.getValue();
+ if (converter != null && itemValue instanceof String)
+ {
+ itemValue = converter.getAsObject(facesContext, uiComponent,
+ (String) itemValue);
+ }
+ else
+ {
+ itemValue = _ClassUtils.convertToType(itemValue, value.getClass());
}
+ return itemValue;
}
+
+}
Added: myfaces/core/trunk/api/src/test/java/javax/faces/component/_SelectItemsUtilTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/test/java/javax/faces/component/_SelectItemsUtilTest.java?rev=1031006&view=auto
==============================================================================
--- myfaces/core/trunk/api/src/test/java/javax/faces/component/_SelectItemsUtilTest.java (added)
+++ myfaces/core/trunk/api/src/test/java/javax/faces/component/_SelectItemsUtilTest.java Thu Nov 4 14:39:49 2010
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+package javax.faces.component;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.myfaces.test.base.junit4.AbstractJsfTestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ *
+ * @author martinkoci
+ */
+public class _SelectItemsUtilTest extends AbstractJsfTestCase
+{
+
+ private static final String NO_SELECTION_ITEM_VALUE = "1.0";
+ private UISelectOne uiComponent;
+ private Float value;
+ private _SelectItemsIterator iterator;
+ private UISelectItem noSelectionOption;
+ private UISelectItem selectItem1;
+ private UISelectItem selectItem2;
+ private UISelectItem selectItem3;
+
+ @Before
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ uiComponent = new UISelectOne();
+
+ value = Float.valueOf("1.2");
+
+ noSelectionOption = new UISelectItem();
+ noSelectionOption.setNoSelectionOption(true);
+ noSelectionOption.setItemValue(NO_SELECTION_ITEM_VALUE);
+ uiComponent.getChildren().add(noSelectionOption);
+
+ selectItem1 = new UISelectItem();
+ selectItem1.setItemValue("1.1");
+ uiComponent.getChildren().add(selectItem1);
+ selectItem2 = new UISelectItem();
+ selectItem2.setItemValue("1.2");
+ uiComponent.getChildren().add(selectItem2);
+ selectItem3 = new UISelectItem();
+ selectItem3.setItemValue("1.3");
+ uiComponent.getChildren().add(selectItem3);
+
+ iterator = new _SelectItemsIterator(uiComponent, facesContext);
+ }
+
+ @After
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+ uiComponent = null;
+ value = null;
+ iterator = null;
+ noSelectionOption = null;
+ selectItem1 = null;
+ selectItem2 = null;
+ selectItem3 = null;
+ }
+
+ @Test
+ public void testMatchValue()
+ {
+
+ boolean matchValue = _SelectItemsUtil.matchValue(facesContext, uiComponent, value, iterator, null);
+
+ assertTrue("Value Float 1.2 must match SelectItem.value \"1.2\" (type of String)", matchValue);
+
+ Float valueNotInSelectItems = Float.valueOf("2.0");
+ matchValue = _SelectItemsUtil.matchValue(facesContext, uiComponent, valueNotInSelectItems, iterator, null);
+ assertFalse(matchValue);
+ }
+
+ @Test @Ignore // TODO martinkoci remove @Ignore after myfaces-test 1.0.1 release
+ public void testMatchValueWithEnums() throws Exception
+ {
+ noSelectionOption.setItemValue("NONE");
+ selectItem1.setItemValue("ONE");
+ selectItem2.setItemValue("TWO");
+ selectItem3.setItemValue("THREE");
+ iterator = new _SelectItemsIterator(uiComponent, facesContext);
+
+ Object enumValue = MockEnum.THREE;
+ boolean matchValue = _SelectItemsUtil.matchValue(facesContext, uiComponent, enumValue, iterator, null);
+
+ assertTrue("Value Enum THREE must match SelectItem.value \"THREE\" (type of String)", matchValue);
+
+ enumValue = MockEnum.FOUR;
+ matchValue = _SelectItemsUtil.matchValue(facesContext, uiComponent, enumValue, iterator, null);
+ assertFalse(matchValue);
+ }
+
+
+ private static enum MockEnum {
+ NONE, ONE,TWO, THREE, FOUR
+ }
+
+ @Test
+ public void testIsNoSelectionOption()
+ {
+ Float value = Float.parseFloat(NO_SELECTION_ITEM_VALUE);
+ boolean noSelectionOption = _SelectItemsUtil.isNoSelectionOption(facesContext, uiComponent, value, iterator, null);
+ assertTrue(noSelectionOption);
+
+ Float valueNotInSelectItems = Float.valueOf("2.0");
+ noSelectionOption = _SelectItemsUtil.isNoSelectionOption(facesContext, uiComponent, valueNotInSelectItems, iterator, null);
+ assertFalse(noSelectionOption);
+
+ }
+
+}