Author: artdaw
Date: 2011-01-27 11:09:53 -0500 (Thu, 27 Jan 2011)
New Revision: 21286
Added:
trunk/ui/common/ui/src/test/java/org/richfaces/component/util/SelectUtilsTest.java
Modified:
trunk/ui/common/ui/src/main/java/org/richfaces/component/util/SelectUtils.java
trunk/ui/input/ui/src/main/java/org/richfaces/renderkit/InputRendererBase.java
Log:
RF-10131: SelectItem(s) compatibility with JSF 2.0 is improved
Modified: trunk/ui/common/ui/src/main/java/org/richfaces/component/util/SelectUtils.java
===================================================================
---
trunk/ui/common/ui/src/main/java/org/richfaces/component/util/SelectUtils.java 2011-01-27
16:08:30 UTC (rev 21285)
+++
trunk/ui/common/ui/src/main/java/org/richfaces/component/util/SelectUtils.java 2011-01-27
16:09:53 UTC (rev 21286)
@@ -21,96 +21,90 @@
package org.richfaces.component.util;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
-import javax.el.ELContext;
import javax.el.ValueExpression;
-import javax.faces.FacesException;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIInput;
-import javax.faces.component.UIOutput;
-import javax.faces.component.UISelectItem;
-import javax.faces.component.UISelectItems;
-import javax.faces.component.UISelectMany;
+import javax.faces.application.ProjectStage;
+import javax.faces.component.*;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.model.SelectItem;
+import java.util.*;
+import java.util.Map.Entry;
-import org.ajax4jsf.Messages;
-import org.richfaces.log.Logger;
-import org.richfaces.log.RichfacesLogger;
-
/**
* @author Maksim Kaszynski
*/
public final class SelectUtils {
private static final Logger LOG = RichfacesLogger.APPLICATION.getLogger();
+
private SelectUtils() {
}
/**
* Gathers all select items from specified component's children
*
- * @param context
- * @param component
- * @return list of {@link SelectItems} taken from f:selectItem and f:selectItems
+ * @param context Faces context
+ * @param component UIComponent with UISelectItem or UISelectItems children
+ * @return list of {@link SelectItem} taken from f:selectItem and f:selectItems
*/
+ @SuppressWarnings("unchecked")
public static List<SelectItem> getSelectItems(FacesContext context, UIComponent
component) {
ArrayList<SelectItem> list = new ArrayList<SelectItem>();
- Iterator<UIComponent> kids = component.getChildren().iterator();
- while (kids.hasNext()) {
- UIComponent kid = kids.next();
+ for (UIComponent uiComponent : component.getChildren()) {
- if (kid instanceof UISelectItem) {
- Object value = ((UISelectItem) kid).getValue();
+ if (uiComponent instanceof UISelectItem) {
+ UISelectItem uiSelectItem = (UISelectItem) uiComponent;
+ Object value = uiSelectItem.getValue();
if (value == null) {
- UISelectItem item = (UISelectItem) kid;
-
+ UISelectItem item = (UISelectItem) uiComponent;
list.add(new SelectItem(item.getItemValue(), item.getItemLabel(),
item.getItemDescription(),
- item.isItemDisabled()));
+ item.isItemDisabled(), item.isItemEscaped(),
item.isNoSelectionOption()));
} else if (value instanceof SelectItem) {
list.add((SelectItem) value);
} else {
- String valueClass = value != null ? "'" +
value.getClass().getName() + "'" : "";
-
- throw new
IllegalArgumentException(Messages.getMessage(Messages.INVALID_ATTRIBUTE_VALUE,
- valueClass, "<selectItem>"));
+ ValueExpression expression =
uiSelectItem.getValueExpression("value");
+ throw new IllegalArgumentException("ValueExpression '"
+ + (expression == null ? null :
expression.getExpressionString()) + "' of UISelectItem : "
+ + RichfacesLogger.getComponentPath(uiComponent) + " does
not reference an Object of type SelectItem");
}
- } else if ((kid instanceof UISelectItems) && (null != context)) {
- Object value = ((UISelectItems) kid).getValue();
+ } else if ((uiComponent instanceof UISelectItems) && (null !=
context)) {
+ UISelectItems currentUISelectItems = ((UISelectItems) uiComponent);
+ Object value = currentUISelectItems.getValue();
if (value instanceof SelectItem) {
list.add((SelectItem) value);
} else if (value instanceof SelectItem[]) {
SelectItem[] items = (SelectItem[]) value;
-
list.addAll(Arrays.asList(items));
} else if (value instanceof Collection) {
list.addAll((Collection<SelectItem>) value);
} else if (value instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) value;
Set<Entry<Object, Object>> entrySet = map.entrySet();
-
for (Entry<Object, Object> entry : entrySet) {
list.add(new SelectItem(entry.getValue(),
entry.getKey().toString(), null));
}
} else {
- String valueClass = (value != null) ? "'" +
value.getClass().getName() + "'" : "";
-
- throw new
IllegalArgumentException(Messages.getMessage(Messages.INVALID_ATTRIBUTE_VALUE,
- valueClass, "<selectItems>"));
+ Logger.Level level = Logger.Level.INFO;
+ if (!context.isProjectStage(ProjectStage.Production)) {
+ level = Logger.Level.WARNING;
+ }
+ if (LOG.isLogEnabled(level)) {
+ ValueExpression expression =
currentUISelectItems.getValueExpression("value");
+ LOG.log(level, String.format("ValueExpression %s of
UISelectItems with component-path %s"
+ + " does not reference an Object of type
SelectItem,"
+ + " array, Iterable or Map, but of type: %s",
+ (expression == null ? null :
expression.getExpressionString()),
+ RichfacesLogger.getComponentPath(uiComponent),
+ (value == null ? null : value.getClass().getName())
+ ));
+ }
}
}
}
@@ -118,156 +112,12 @@
return list;
}
- /**
- * Converts UISelectMany submitted value to converted value
- *
- * @param facesContext
- * @param component
- * @param submittedValue
- * @return
- * @throws ConverterException
- * @author Manfred Geiler
- */
- public static Object getConvertedUISelectManyValue(FacesContext facesContext,
UISelectMany component,
- String[] submittedValue) throws
ConverterException {
-
- // Attention!
- // This code is duplicated in jsfapi component package.
- // If you change something here please do the same in the other class!
- if (submittedValue == null) {
- throw new NullPointerException("submittedValue");
- }
-
- ELContext elContext = facesContext.getELContext();
- ValueExpression vb = component.getValueExpression("value");
- Class<?> valueType = null;
- Class<?> arrayComponentType = null;
-
- if (vb != null) {
- valueType = vb.getType(elContext);
-
- if ((valueType != null) && valueType.isArray()) {
- arrayComponentType = valueType.getComponentType();
- }
- }
-
- Converter converter = component.getConverter();
-
- if (converter == null) {
- if (valueType == null) {
-
- // No converter, and no idea of expected type
- // --> return the submitted String array
- return submittedValue;
- }
-
- if (List.class.isAssignableFrom(valueType)) {
-
- // expected type is a List
- // --> according to javadoc of UISelectMany we assume that the
- // element type
- // is java.lang.String, and copy the String array to a new List
- List<String> lst = Arrays.asList(submittedValue);
-
- return lst;
- }
-
- if (arrayComponentType == null) {
- throw new
IllegalArgumentException(Messages.getMessage(Messages.VALUE_BINDING_TYPE_ERROR));
- }
-
- if (String.class.equals(arrayComponentType)) {
- return submittedValue; // No conversion needed for String type
- }
-
- if (Object.class.equals(arrayComponentType)) {
- return submittedValue; // No conversion for Object class
- }
-
- try {
- converter =
facesContext.getApplication().createConverter(arrayComponentType);
- } catch (FacesException e) {
- LOG.error(Messages.getMessage(Messages.NO_CONVERTER_FOUND_ERROR,
arrayComponentType.getName()), e);
-
- return submittedValue;
- }
- }
-
- // Now, we have a converter...
- if (valueType == null) {
-
- // ...but have no idea of expected type
- // --> so let's convert it to an Object array
- int len = submittedValue.length;
- Object[] convertedValues = (Object[]) Array.newInstance((arrayComponentType
== null)
- ? Object.class : arrayComponentType, len);
-
- for (int i = 0; i < len; i++) {
- convertedValues[i] = converter.getAsObject(facesContext, component,
submittedValue[i]);
- }
-
- return convertedValues;
- }
-
- if (List.class.isAssignableFrom(valueType)) {
-
- // Curious case: According to specs we should assume, that the
- // element type
- // of this List is java.lang.String. But there is a Converter set
- // for this
- // component. Because the user must know what he is doing, we will
- // convert the values.
- int len = submittedValue.length;
- List<Object> lst = new ArrayList<Object>(len);
-
- for (int i = 0; i < len; i++) {
- lst.add(converter.getAsObject(facesContext, component,
submittedValue[i]));
- }
-
- return lst;
- }
-
- if (arrayComponentType == null) {
- throw new
IllegalArgumentException(Messages.getMessage(Messages.VALUE_BINDING_TYPE_ERROR));
- }
-
- if (arrayComponentType.isPrimitive()) {
-
- // primitive array
- int len = submittedValue.length;
- Object convertedValues = Array.newInstance(arrayComponentType, len);
-
- for (int i = 0; i < len; i++) {
- Array.set(convertedValues, i, converter.getAsObject(facesContext,
component, submittedValue[i]));
- }
-
- return convertedValues;
- } else {
-
- // Object array
- int len = submittedValue.length;
- ArrayList<Object> convertedValues = new ArrayList<Object>(len);
-
- for (int i = 0; i < len; i++) {
- convertedValues.add(i, converter.getAsObject(facesContext, component,
submittedValue[i]));
- }
-
- return convertedValues.toArray((Object[])
Array.newInstance(arrayComponentType, len));
- }
- }
-
- public static Object getConvertedUIInputValue(FacesContext facesContext, UIInput
component, String submittedValue)
- throws ConverterException {
-
- /*
- * if (submittedValue == null)
- * throw new NullPointerException("submittedValue");
- */
+ public static Object getConvertedUIInputValue(FacesContext facesContext, UIInput
component, String submittedValue) throws ConverterException {
if (InputUtils.EMPTY_STRING.equals(submittedValue)) {
return null;
}
- Converter converter = getConverterForProperty(facesContext, component,
"value");
+ Converter converter = SelectUtils.findConverter(facesContext, component,
"value");
if (converter != null) {
return converter.getAsObject(facesContext, component, submittedValue);
}
@@ -275,48 +125,13 @@
return submittedValue;
}
- /**
- * @param facesContext
- * @param component
- * @param property
- * @return converter for specified component attribute
- * @deprecated use SelectUtils.findConverter instead
- */
-
- @Deprecated
- public static Converter getConverterForProperty(FacesContext facesContext, UIOutput
component, String property) {
- Converter converter = component.getConverter();
-
- if (converter == null) {
- ValueExpression ve = component.getValueExpression(property);
-
- if (ve != null) {
- Class<?> valueType = ve.getType(facesContext.getELContext());
-
- if ((valueType == null) || Object.class.equals(valueType)) {
-
- // No converter needed
- } else {
- converter =
facesContext.getApplication().createConverter(valueType);
-
- if (converter == null && !String.class.equals(valueType)) {
- throw new
ConverterException(Messages.getMessage(Messages.NO_CONVERTER_FOUND_ERROR,
- valueType.getName()));
- }
- }
- }
- }
-
- return converter;
- }
-
public static Converter findConverter(FacesContext facesContext, UIOutput component,
String property) {
Converter converter = component.getConverter();
if (converter == null) {
ValueExpression ve = component.getValueExpression(property);
-
+
if (ve != null) {
Class<?> valueType = ve.getType(facesContext.getELContext());
@@ -325,11 +140,11 @@
} else {
converter =
facesContext.getApplication().createConverter(valueType);
}
-
+
}
}
return converter;
}
-
+
}
Added: trunk/ui/common/ui/src/test/java/org/richfaces/component/util/SelectUtilsTest.java
===================================================================
--- trunk/ui/common/ui/src/test/java/org/richfaces/component/util/SelectUtilsTest.java
(rev 0)
+++
trunk/ui/common/ui/src/test/java/org/richfaces/component/util/SelectUtilsTest.java 2011-01-27
16:09:53 UTC (rev 21286)
@@ -0,0 +1,112 @@
+package org.richfaces.component.util;
+
+import org.jboss.test.faces.AbstractFacesTest;
+import org.junit.Assert;
+
+import javax.faces.component.UIParameter;
+import javax.faces.component.UISelectItem;
+import javax.faces.component.UISelectOne;
+import javax.faces.model.SelectItem;
+import java.util.List;
+
+/**
+ * @author Gleb Galkin
+ * @since 27.01.11
+ */
+public class SelectUtilsTest extends AbstractFacesTest {
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ setupFacesRequest();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * The aim of this test is to check first part of {@link SelectUtils#getSelectItems},
for {@link UISelectOne}
+ */
+ public void testGetSelectItem() {
+ UISelectOne selectOne = new UISelectOne();
+ selectOne.getChildren().add(new UISelectItemStub("value1",
"label1", "description1", false, false, false));
+ selectOne.getChildren().add(new UISelectItemStub("value2",
"label2", "description2", false, true, true));
+
+ UISelectItem item = new UISelectItem();
+ item.setValue(new SelectItem("value3", "label3",
"description3", true, true, true));
+ selectOne.getChildren().add(item);
+
+ // non select item at end
+ UIParameter param = new UIParameter();
+ param.setName("param");
+ param.setValue("paramValue");
+ selectOne.getChildren().add(param);
+
+ checkSelectItems(SelectUtils.getSelectItems(facesContext, selectOne));
+
+ // non select item in middle
+ selectOne = new UISelectOne();
+ selectOne.getChildren().add(new UISelectItemStub("value1",
"label1", "description1", false, false, false));
+ selectOne.getChildren().add(param);
+ selectOne.getChildren().add(new UISelectItemStub("value2",
"label2", "description2", false, true, true));
+ checkTwoSelectItems(SelectUtils.getSelectItems(facesContext, selectOne));
+
+ // non select item as value cause IllegalArgumentException
+ item = new UISelectItem();
+ item.setValue(new UISelectItem());
+ selectOne.getChildren().add(item);
+ try {
+ SelectUtils.getSelectItems(facesContext, selectOne);
+ } catch (Exception e) {
+ if (!(e instanceof IllegalArgumentException)) {
+ Assert.fail("Non select item as value should cause
IllegalArgumentException");
+ }
+ }
+ }
+
+ private void checkSelectItems(List<SelectItem> selectItems) {
+ checkTwoSelectItems(selectItems);
+
+ Assert.assertNotNull(selectItems.get(2));
+ Assert.assertEquals("value3", selectItems.get(2).getValue());
+ Assert.assertEquals("label3", selectItems.get(2).getLabel());
+ Assert.assertEquals("description3",
selectItems.get(2).getDescription());
+ Assert.assertEquals(true, selectItems.get(2).isDisabled());
+ Assert.assertEquals(true, selectItems.get(2).isEscape());
+ Assert.assertEquals(true, selectItems.get(2).isNoSelectionOption());
+ }
+
+ private void checkTwoSelectItems(List<SelectItem> selectItems) {
+ Assert.assertNotNull(selectItems.get(0));
+ Assert.assertEquals("value1", selectItems.get(0).getValue());
+ Assert.assertEquals("label1", selectItems.get(0).getLabel());
+ Assert.assertEquals("description1",
selectItems.get(0).getDescription());
+ Assert.assertEquals(false, selectItems.get(0).isDisabled());
+ Assert.assertEquals(false, selectItems.get(0).isEscape());
+ Assert.assertEquals(false, selectItems.get(0).isNoSelectionOption());
+
+ Assert.assertNotNull(selectItems.get(1));
+ Assert.assertEquals("value2", selectItems.get(1).getValue());
+ Assert.assertEquals("label2", selectItems.get(1).getLabel());
+ Assert.assertEquals("description2",
selectItems.get(1).getDescription());
+ Assert.assertEquals(false, selectItems.get(1).isDisabled());
+ Assert.assertEquals(true, selectItems.get(1).isEscape());
+ Assert.assertEquals(true, selectItems.get(1).isNoSelectionOption());
+ }
+
+ private class UISelectItemStub extends UISelectItem {
+
+ public UISelectItemStub(Object itemValue, String itemLabel, String
itemDescription,
+ boolean itemDisabled, boolean itemEscaped, boolean
noSelectionOption) {
+ super();
+ setItemValue(itemValue);
+ setItemLabel(itemLabel);
+ setItemDescription(itemDescription);
+ setItemDisabled(itemDisabled);
+ setItemEscaped(itemEscaped);
+ setNoSelectionOption(noSelectionOption);
+ }
+ }
+}
Modified: trunk/ui/input/ui/src/main/java/org/richfaces/renderkit/InputRendererBase.java
===================================================================
---
trunk/ui/input/ui/src/main/java/org/richfaces/renderkit/InputRendererBase.java 2011-01-27
16:08:30 UTC (rev 21285)
+++
trunk/ui/input/ui/src/main/java/org/richfaces/renderkit/InputRendererBase.java 2011-01-27
16:09:53 UTC (rev 21286)
@@ -22,16 +22,15 @@
package org.richfaces.renderkit;
-import java.util.Map;
+import org.richfaces.component.util.SelectUtils;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
+import java.util.Map;
-import org.richfaces.component.util.SelectUtils;
-
/**
* @author Nick Belaevski - nbelaevski(a)exadel.com
* created 23.01.2007
@@ -60,7 +59,7 @@
if (value == null) {
Object curVal = input.getValue();
- Converter converter = SelectUtils.getConverterForProperty(context, input,
"value");
+ Converter converter = SelectUtils.findConverter(context, input,
"value");
if (converter != null) {
value = converter.getAsString(context, input, curVal);