dev@javaserverfaces.java.net

Re: Seeking Review Re: [451-noSelection] PROPOSAL

From: Ryan Lubke <Ryan.Lubke_at_Sun.COM>
Date: Thu, 04 Dec 2008 12:21:02 -0800

Are any mods required for the option rendering section of the RenderKit
docs?
>
>
> SECTION: Modified Files
> ----------------------------
> M jsf-api/src/javax/faces/model/SelectItem.java
>
> - Modify 5 arg ctor to be 6 arg ctor where the last arg is the boolean
> value of the noSelectionOption property.
>
> - Modify places where 5 arg ctor is called to call 6 arg ctor.
>
> - add boolean noSelectionOption JavaBeans property
>
The new methods lack proper javadocs.
>
>
> M jsf-api/src/javax/faces/component/UISelectItem.java
>
> - add boolean noSelectionOption JavaBeans property
>
The new methods lack javadocs.

More inlined below.
>
>
> Index: jsf-api/src/javax/faces/component/SelectUtils.java
> ===================================================================
> --- jsf-api/src/javax/faces/component/SelectUtils.java (revision 5995)
> +++ jsf-api/src/javax/faces/component/SelectUtils.java (working copy)
> @@ -75,11 +75,11 @@
> static boolean matchValue(FacesContext ctx,
> UIComponent component,
> Object value,
> - Iterator items,
> + Iterator<SelectItem> items,
> Converter converter) {
>
> while (items.hasNext()) {
> - SelectItem item = (SelectItem) items.next();
> + SelectItem item = items.next();
> if (item instanceof SelectItemGroup) {
> SelectItem subitems[] =
> ((SelectItemGroup) item).getSelectItems();
> @@ -89,27 +89,17 @@
> }
> }
> } else {
> - Object itemValue = item.getValue();
> - if (itemValue == null && value == null) {
> - return (true);
> - }
> - if ((value == null) ^ (itemValue == null)) {
> + Object compareValue = null;
> +
> + try {
> + compareValue = doConversion(ctx, component, item, value,
> + converter);
> + } catch (IllegalStateException ise) {
> continue;
> }
> - Object compareValue;
> - if (converter == null) {
> - compareValue =
> - coerceToModelType(ctx, itemValue, value.getClass());
> - } else {
> - compareValue = itemValue;
> - if (compareValue instanceof String
> - && !(value instanceof String)) {
> - // type mismatch between the time and the value we're
> - // comparing. Invoke the Converter.
> - compareValue = converter.getAsObject(ctx,
> - component,
> - (String) compareValue);
> - }
> +
> + if (null == compareValue && null == value) {
> + return true;
> }
>
> if (value.equals(compareValue)) {
> @@ -120,8 +110,90 @@
> return (false);
>
> }
> +
> + /**
> + * Returns true iff component has a {_at_link UISelectItem} child
> + * whose itemValue exactly matches the argument value
> + * @param ctx
> + * @param component
> + * @param value
> + * @param items
> + * @return
> + */
> +
> + static boolean valueIsNoSelectionOption(FacesContext ctx,
> + UIComponent component,
> + Object value,
> + Iterator<SelectItem> items,
> + Converter converter) {
> + boolean result = false;
> +
> + while (items.hasNext()) {
> + SelectItem item = items.next();
> + if (item instanceof SelectItemGroup) {
> + SelectItem subitems[] =
> + ((SelectItemGroup) item).getSelectItems();
> + if ((subitems != null) && (subitems.length > 0)) {
> + if (valueIsNoSelectionOption(ctx, component, value, new ArrayIterator(subitems), converter)) {
> + result = true;
> + break;
> + }
> + }
> + } else {
> + Object compareValue = null;
> +
> + try {
> + compareValue = doConversion(ctx, component, item, value,
> + converter);
> + } catch (IllegalStateException ise) {
> + continue;
> + }
> +
> + if (null == compareValue && null == value &&
> + item.isNoSelectionOption()) {
> + result = true;
> + break;
> + } else if (value.equals(compareValue) && item.isNoSelectionOption()) {
> + result = true;
> + break;
> + }
> + }
> +
> + }
> +
> + return result;
> + }
> +
> + private static Object doConversion(FacesContext ctx,
> + UIComponent component, SelectItem item,
> + Object value, Converter converter) throws IllegalStateException {
> + Object itemValue = item.getValue();
> + if (itemValue == null && value == null) {
> + return (null);
> + }
> + if ((value == null) ^ (itemValue == null)) {
> + throw new IllegalStateException("XOR comparison failed");
> + }
>
Not a very helpful error message. I'd rather see something more
descriptive.
> + Object compareValue;
> + if (converter == null) {
> + compareValue =
> + coerceToModelType(ctx, itemValue, value.getClass());
> + } else {
> + compareValue = itemValue;
> + if (compareValue instanceof String
> + && !(value instanceof String)) {
> + // type mismatch between the time and the value we're
> + // comparing. Invoke the Converter.
> + compareValue = converter.getAsObject(ctx,
> + component,
> + (String) compareValue);
> + }
> + }
>
> + return compareValue;
> + }
>
> +
> /**
> * Coerce the provided value to the specified type using EL coercion.
> *
>
>