public boolean hasNext()

in tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyRendererBase.java [519:629]


    public boolean hasNext() {
      if (nextItem != null) {
        return true;
      }
      if (nestedItems != null) {
        if (nestedItems.hasNext()) {
          return true;
        }
        nestedItems = null;
        currentComponent = null;
      }
      if (children.hasNext()) {
        UIComponent child = children.next();
        // When there is other components nested that does
        // not extends from UISelectItem or UISelectItems
        // the behavior for this iterator is just skip this
        // element(s) until an element that extends from these
        // classes are found. If there is no more elements
        // that conform this condition, just return false.
        while (!(child instanceof UISelectItem) && !(child instanceof UISelectItems)) {
          // Try to skip it
          if (children.hasNext()) {
            // Skip and do the same check
            child = children.next();
          } else {
            // End loop, so the final result is return false,
            // since there are no more components to iterate.
            return false;
          }
        }
        if (child instanceof UISelectItem) {
          final UISelectItem uiSelectItem = (UISelectItem) child;
          Object item = uiSelectItem.getValue();
          if (item == null) {
            // no value attribute --> create the SelectItem out of the other attributes
            final Object itemValue = uiSelectItem.getItemValue();
            String label = uiSelectItem.getItemLabel();
            final String description = uiSelectItem.getItemDescription();
            final boolean disabled = uiSelectItem.isItemDisabled();
            final boolean escape = uiSelectItem.isItemEscaped();
            final boolean noSelectionOption = uiSelectItem.isNoSelectionOption();
            if (label == null) {
              label = itemValue.toString();
            }
            item = new SelectItem(itemValue, label, description, disabled, escape, noSelectionOption);
          } else if (!(item instanceof SelectItem)) {
            final ValueExpression expression = uiSelectItem.getValueExpression("value");
            throw new IllegalArgumentException("ValueExpression '"
                + (expression == null ? null : expression.getExpressionString()) + "' of UISelectItem : "
                + getPathToComponent(child) + " does not reference an Object of type SelectItem");
          }
          nextItem = (SelectItem) item;
          currentComponent = child;
          return true;
        } else if (child instanceof UISelectItems) {
          currentUISelectItems = (UISelectItems) child;
          final Object value = currentUISelectItems.getValue();
          currentComponent = child;

          if (value instanceof SelectItem) {
            nextItem = (SelectItem) value;
            return true;
          } else if (value != null && value.getClass().isArray()) {
            // value is any kind of array (primitive or non-primitive)
            // --> we have to use class Array to get the values
            final int length = Array.getLength(value);
            final Collection<Object> items = new ArrayList<>(length);
            for (int i = 0; i < length; i++) {
              items.add(Array.get(value, i));
            }
            nestedItems = items.iterator();
            return hasNext();
          } else if (value instanceof Iterable) {
            // value is Iterable --> Collection, DataModel,...
            nestedItems = ((Iterable<?>) value).iterator();
            return hasNext();
          } else if (value instanceof Map) {
            final Map<Object, Object> map = (Map<Object, Object>) value;
            final Collection<SelectItem> items = new ArrayList<>(map.size());
            for (final Map.Entry<Object, Object> entry : map.entrySet()) {
              items.add(new SelectItem(entry.getValue(), entry.getKey().toString()));
            }

            nestedItems = items.iterator();
            return hasNext();
          } else {

            if (facesContext.isProjectStage(ProjectStage.Production) && LOG.isDebugEnabled()
                || LOG.isWarnEnabled()) {
              final ValueExpression expression = currentUISelectItems.getValueExpression("value");
              final Object[] objects = {
                  expression == null ? null : expression.getExpressionString(),
                  getPathToComponent(child),
                  value == null ? null : value.getClass().getName()
              };
              final String message = "ValueExpression {0} of UISelectItems with component-path {1}"
                  + " does not reference an Object of type SelectItem,"
                  + " array, Iterable or Map, but of type: {2}";
              if (facesContext.isProjectStage(ProjectStage.Production)) {
                LOG.debug(message, objects);
              } else {
                LOG.warn(message, objects);
              }
            }
          }
        } else {
          currentComponent = null;
        }
      }
      return false;
    }