Save This Page
Home » mojarra-1.2_09-b02-FCS-source » javax.faces.component » [javadoc | source]
    1   /*
    2    * $Id: UISelectOne.java,v 1.56 2007/07/27 19:59:08 rlubke Exp $
    3    */
    4   
    5   /*
    6    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    7    * 
    8    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    9    * 
   10    * The contents of this file are subject to the terms of either the GNU
   11    * General Public License Version 2 only ("GPL") or the Common Development
   12    * and Distribution License("CDDL") (collectively, the "License").  You
   13    * may not use this file except in compliance with the License. You can obtain
   14    * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   15    * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   16    * language governing permissions and limitations under the License.
   17    * 
   18    * When distributing the software, include this License Header Notice in each
   19    * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   20    * Sun designates this particular file as subject to the "Classpath" exception
   21    * as provided by Sun in the GPL Version 2 section of the License file that
   22    * accompanied this code.  If applicable, add the following below the License
   23    * Header, with the fields enclosed by brackets [] replaced by your own
   24    * identifying information: "Portions Copyrighted [year]
   25    * [name of copyright owner]"
   26    * 
   27    * Contributor(s):
   28    * 
   29    * If you wish your version of this file to be governed by only the CDDL or
   30    * only the GPL Version 2, indicate your decision by adding "[Contributor]
   31    * elects to include this software in this distribution under the [CDDL or GPL
   32    * Version 2] license."  If you don't indicate a single choice of license, a
   33    * recipient has the option to distribute your version of this file under
   34    * either the CDDL, the GPL Version 2 or to extend the choice of license to
   35    * its licensees as provided above.  However, if you add GPL Version 2 code
   36    * and therefore, elected the GPL Version 2 license, then the option applies
   37    * only if the new code is made subject to such option by the copyright
   38    * holder.
   39    */
   40   
   41   package javax.faces.component;
   42   
   43   
   44   import javax.el.ELException;
   45   import javax.faces.application.FacesMessage;
   46   import javax.faces.context.FacesContext;
   47   import javax.faces.model.SelectItem;
   48   import javax.faces.model.SelectItemGroup;
   49   
   50   import java.util.Iterator;
   51   import java.util.NoSuchElementException;
   52   
   53   
   54   /**
   55    * <p><strong>UISelectOne</strong> is a {@link UIComponent} that represents
   56    * the user's choice of zero or one items from among a discrete set of
   57    * available options.  The user can modify the selected value.  Optionally,
   58    * the component can be preconfigured with a currently selected item, by
   59    * storing it as the <code>value</code> property of the component.</p>
   60    *
   61    * <p>This component is generally rendered as a select box or a group of
   62    * radio buttons.</p>
   63    *
   64    * <p>By default, the <code>rendererType</code> property is set to
   65    * "<code>javax.faces.Menu</code>".  This value can be changed by
   66    * calling the <code>setRendererType()</code> method.</p>
   67    */
   68   
   69   public class UISelectOne extends UIInput {
   70   
   71   
   72       // ------------------------------------------------------ Manifest Constants
   73   
   74   
   75       /**
   76        * <p>The standard component type for this component.</p>
   77        */
   78       public static final String COMPONENT_TYPE = "javax.faces.SelectOne";
   79   
   80   
   81       /**
   82        * <p>The standard component family for this component.</p>
   83        */
   84       public static final String COMPONENT_FAMILY = "javax.faces.SelectOne";
   85   
   86   
   87       /**
   88        * <p>The message identifier of the
   89        * {@link javax.faces.application.FacesMessage} to be created if
   90        * a value not matching the available options is specified.
   91        */
   92       public static final String INVALID_MESSAGE_ID =
   93           "javax.faces.component.UISelectOne.INVALID";
   94   
   95   
   96       // ------------------------------------------------------------ Constructors
   97   
   98   
   99       /**
  100        * <p>Create a new {@link UISelectOne} instance with default property
  101        * values.</p>
  102        */
  103       public UISelectOne() {
  104   
  105           super();
  106           setRendererType("javax.faces.Menu");
  107   
  108       }
  109   
  110   
  111       // -------------------------------------------------------------- Properties
  112   
  113   
  114       public String getFamily() {
  115   
  116           return (COMPONENT_FAMILY);
  117   
  118       }
  119   
  120   
  121       // ------------------------------------------------------ Validation Methods
  122   
  123   
  124       /**
  125        * <p>In addition to the standard validation behavior inherited from
  126        * {@link UIInput}, ensure that any specified value is equal to one of
  127        * the available options.  Before comparing each option, coerce the 
  128        * option value type to the type of this component's value following
  129        * the Expression Language coercion rules.  If the specified value is 
  130        * not equal to any of the options,  enqueue an error message
  131        * and set the <code>valid</code> property to <code>false</code>.</p>
  132        *
  133        * @param context The {@link FacesContext} for the current request
  134        *
  135        * @param value The converted value to test for membership.
  136        *
  137        * @throws NullPointerException if <code>context</code>
  138        *  is <code>null</code>
  139        */
  140       protected void validateValue(FacesContext context, Object value) {
  141   
  142           // Skip validation if it is not necessary
  143           super.validateValue(context, value);
  144   
  145           if (!isValid() || (value == null)) {
  146               return;
  147           }
  148   
  149           // Ensure that the value matches one of the available options
  150           boolean found = matchValue(value, new SelectItemsIterator(this));
  151   
  152           // Enqueue an error message if an invalid value was specified
  153           if (!found) {
  154               FacesMessage message =
  155                   MessageFactory.getMessage(context, INVALID_MESSAGE_ID,
  156                        MessageFactory.getLabel(context, this));
  157               context.addMessage(getClientId(context), message);
  158               setValid(false);
  159           }
  160       }
  161   
  162   
  163       // --------------------------------------------------------- Private Methods
  164   
  165   
  166       /**
  167        * <p>Return <code>true</code> if the specified value matches one of the
  168        * available options, performing a recursive search if if a
  169        * {@link SelectItemGroup} instance is detected.</p>
  170        *
  171        * @param value {@link UIComponent} value to be tested
  172        * @param items Iterator over the {@link SelectItem}s to be checked
  173        */
  174       private boolean matchValue(Object value, Iterator items) {
  175   
  176           while (items.hasNext()) {
  177               SelectItem item = (SelectItem) items.next();
  178               if (item instanceof SelectItemGroup) {
  179                   SelectItem subitems[] =
  180                       ((SelectItemGroup) item).getSelectItems();
  181                   if ((subitems != null) && (subitems.length > 0)) {
  182                       if (matchValue(value, new ArrayIterator(subitems))) {
  183                           return (true);
  184                       }
  185                   }
  186               } else {
  187                   //Coerce the item value type before comparing values.
  188                   Class type = value.getClass();
  189                   Object newValue;
  190                   try {
  191                       newValue = getFacesContext().getApplication().
  192                           getExpressionFactory().coerceToType(item.getValue(), type);
  193                   } catch (ELException ele) {
  194                       newValue = item.getValue();
  195                   } catch (IllegalArgumentException iae) {
  196                       // If coerceToType fails, per the docs it should throw
  197                       // an ELException, however, GF 9.0 and 9.0u1 will throw
  198                       // an IllegalArgumentException instead (see GF issue 1527).                    
  199                       newValue = item.getValue();
  200                   }
  201                   if (value.equals(newValue)) {
  202                       return (true);
  203                   }
  204               }
  205           }
  206           return (false);
  207   
  208       }
  209   
  210   
  211       static class ArrayIterator implements Iterator {
  212   
  213           public ArrayIterator(Object items[]) {
  214               this.items = items;
  215           }
  216   
  217           private Object items[];
  218           private int index = 0;
  219   
  220           public boolean hasNext() {
  221               return (index < items.length);
  222           }
  223   
  224           public Object next() {
  225               try {
  226                   return (items[index++]);
  227               } catch (IndexOutOfBoundsException e) {
  228                   throw new NoSuchElementException();
  229               }
  230           }
  231   
  232           public void remove() {
  233               throw new UnsupportedOperationException();
  234           }
  235       }
  236   
  237   
  238   }

Save This Page
Home » mojarra-1.2_09-b02-FCS-source » javax.faces.component » [javadoc | source]