View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied.  See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  package org.apache.myfaces.shared_orchestra.util;
    20
    21  import java.util.ArrayList;
    22  import java.util.Arrays;
    23  import java.util.Collection;
    24  import java.util.Iterator;
    25  import java.util.Map;
    26  import java.util.NoSuchElementException;
    27
    28  import javax.faces.component.UIComponent;
    29  import javax.faces.component.UISelectItem;
    30  import javax.faces.component.UISelectItems;
    31  import javax.faces.el.ValueBinding;
    32  import javax.faces.model.SelectItem;
    33
    34  import org.apache.myfaces.shared_orchestra.renderkit.RendererUtils;
    35
    36  /**
    37   * @author Mathias Broekelmann (latest modification by $Author$)
    38   * @version $Revision$ $Date$
    39   */
    40  public class SelectItemsIterator implements Iterator
    41  {
    42      private final Iterator _childs;
    43      private Iterator _nestedItems;
    44      private Object _nextItem;
    45      private String _collectionLabel;
    46      private UISelectItems _currentUISelectItems;
    47
    48      public SelectItemsIterator(UIComponent selectItemsParent)
    49      {
    50          _childs = selectItemsParent.getChildren().iterator();
    51      }
    52
    53      public boolean hasNext()
    54      {
    55          if(_nextItem != null)
    56          {
    57              return true;
    58          }
    59          if(_nestedItems != null)
    60          {
    61              if(_nestedItems.hasNext())
    62              {
    63                  return true;
    64              }
    65              _nestedItems = null;
    66          }
    67          if (_childs.hasNext())
    68          {
    69              UIComponent child = (UIComponent) _childs.next();
    70              // When there is other components nested that does
    71              // not extends from UISelectItem or UISelectItems
    72              // the behavior for this iterator is just skip this
    73              // element(s) until an element that extends from these
    74              // classes are found. If there is no more elements
    75              // that conform this condition, just return false.
    76              while (!(child instanceof UISelectItem)
    77                      && !(child instanceof UISelectItems))
    78              {
    79                  //Try to skip it
    80                  if (_childs.hasNext())
    81                  {
    82                      //Skip and do the same check
    83                      child = (UIComponent) _childs.next();
    84                  }
    85                  else
    86                  {
    87                      //End loop, so the final result is return false,
    88                      //since there are no more components to iterate.
    89                      return false;
    90                  }
    91              }
    92              if (child instanceof UISelectItem)
    93              {
    94                  UISelectItem uiSelectItem = (UISelectItem) child;
    95                  Object item = uiSelectItem.getValue();
    96                  if (item == null)
    97                  {
    98                      Object itemValue = ((UISelectItem) child).getItemValue();
    99                      String label = ((UISelectItem) child).getItemLabel();
    100                     String description = ((UISelectItem) child)
    101                                     .getItemDescription();
    102                     boolean disabled = ((UISelectItem) child).isItemDisabled();
    103                     if (label == null)
    104                     {
    105                         label = itemValue.toString();
    106                     }
    107                     item = new SelectItem(itemValue, label, description,
    108                                     disabled);
    109                 }
    110                 else if (!(item instanceof SelectItem))
    111                 {
    112                     ValueBinding binding = ((UISelectItem) child)
    113                                     .getValueBinding("value");
    114                     throw new IllegalArgumentException(
    115                                     "Value binding '"
    116                                     + (binding == null ? null : binding.getExpressionString())
    117                                     + "' of UISelectItem : "
    118                                     + RendererUtils.getPathToComponent(child)
    119                                     + " does not reference an Object of type SelectItem");
    120                 }
    121                 _nextItem = item;
    122                 return true;
    123             }
    124             else if (child instanceof UISelectItems)
    125             {
    126                 _currentUISelectItems = ((UISelectItems) child);
    127                 Object value = _currentUISelectItems.getValue();
    128
    129                 if (value instanceof SelectItem)
    130                 {
    131                     _nextItem = value;
    132                     return true;
    133                 }
    134                 else if (value instanceof SelectItem[])
    135                 {
    136                     _nestedItems = Arrays.asList((SelectItem[]) value)
    137                                     .iterator();
    138                     _collectionLabel = "Array";
    139                     return hasNext();
    140                 }
    141                 else if (value instanceof Collection)
    142                 {
    143                     _nestedItems = ((Collection)value).iterator();
    144                     _collectionLabel = "Collection";
    145                     return hasNext();
    146                 }
    147                 else if (value instanceof Map)
    148                 {
    149                     Map map = ((Map) value);
    150                     Collection items = new ArrayList(map.size());
    151                     for (Iterator it = map.entrySet().iterator(); it
    152                                     .hasNext();)
    153                     {
    154                         Map.Entry entry = (Map.Entry) it.next();
    155                         items.add(new SelectItem(entry.getValue(), entry
    156                                         .getKey().toString()));
    157                     }
    158                     _nestedItems = items.iterator();
    159                     _collectionLabel = "Map";
    160                     return hasNext();
    161                 }
    162                 else
    163                 {
    164                     ValueBinding binding = _currentUISelectItems.getValueBinding("value");
    165
    166                     throw new IllegalArgumentException(
    167                         "Value binding '"
    168                         + (binding == null ? null : binding
    169                                         .getExpressionString())
    170                         + "'of UISelectItems with component-path "
    171                         + RendererUtils.getPathToComponent(child)
    172                         + " does not reference an Object of type SelectItem, SelectItem[], Collection or Map but of type : "
    173                         + ((value == null) ? null : value
    174                                         .getClass()
    175                                         .getName()));
    176                 }
    177             }
    178         }
    179         return false;
    180     }
    181
    182     public Object next()
    183     {
    184         if (!hasNext())
    185         {
    186             throw new NoSuchElementException();
    187         }
    188         if(_nextItem != null)
    189         {
    190             Object value = _nextItem;
    191             _nextItem = null;
    192             return value;
    193         }
    194         if (_nestedItems != null)
    195         {
    196             Object item = _nestedItems.next();
    197             if (!(item instanceof SelectItem))
    198             {
    199                 ValueBinding binding = _currentUISelectItems
    200                                 .getValueBinding("value");
    201                 throw new IllegalArgumentException(
    202                 _collectionLabel + " referenced by UISelectItems with binding '"
    203                 + binding.getExpressionString()
    204                 + "' and Component-Path : " + RendererUtils.getPathToComponent(_currentUISelectItems)
    205                 + " does not contain Objects of type SelectItem");
    206             }
    207             return item;
    208         }
    209         throw new NoSuchElementException();
    210     }
    211
    212     public void remove()
    213     {
    214         throw new UnsupportedOperationException();
    215     }
    216 }