All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.faces.component.SelectItemsIterator Maven / Gradle / Ivy

Go to download

Jakarta Faces defines an MVC framework for building user interfaces for web applications, including UI components, state management, event handing, input validation, page navigation, and support for internationalization and accessibility.

There is a newer version: 4.1.0
Show newest version
/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package javax.faces.component;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Map;
import java.util.ListIterator;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.lang.reflect.Array;

import javax.faces.model.SelectItem;
import javax.faces.context.FacesContext;
import javax.el.ValueExpression;

/**
 * 

* Package private class for iterating over the set of {@link SelectItem}s for a parent * {@link UISelectMany} or {@link UISelectOne}. *

* * // RELEASE_PENDING (rlubke,driscoll) performanc review */ final class SelectItemsIterator implements Iterator { // ------------------------------------------------------------ Constructors /** *

* Construct an iterator instance for the specified parent component. *

* * @param ctx the {@link FacesContext} for the current request * @param parent The parent {@link UIComponent} whose children will be processed */ public SelectItemsIterator(FacesContext ctx, UIComponent parent) { kids = parent.getChildren().listIterator(); this.ctx = ctx; } // ------------------------------------------------------ Instance Variables /** *

* Iterator over the SelectItem elements pointed at by a UISelectItems component, * or null. *

*/ private Iterator items; /** *

* Iterator over the children of the parent component. *

*/ private ListIterator kids; /** * Expose single SelectItems via an Iterator. This iterator will be reset/reused for each * individual SelectItem instance encountered. */ private SingleElementIterator singleItemIterator; /** * The {@link FacesContext} for the current request. */ private FacesContext ctx; // -------------------------------------------------------- Iterator Methods /** *

* Return true if the iteration has more elements. *

*/ @Override public boolean hasNext() { if (items != null) { if (items.hasNext()) { return (true); } else { items = null; } } Object next = findNextValidChild(); while (next != null) { initializeItems(next); if (items != null) { return true; } else { next = findNextValidChild(); } } return false; } /** *

* Return the next element in the iteration. *

* * @throws NoSuchElementException if there are no more elements */ @SuppressWarnings({ "unchecked" }) @Override public SelectItem next() { if (!hasNext()) { throw new NoSuchElementException(); } if (items != null) { return (items.next()); } return next(); } /** *

* Throw UnsupportedOperationException. *

*/ @Override public void remove() { throw new UnsupportedOperationException(); } // --------------------------------------------------------- Private Methods /** *

* Initializes the items instance variable with an Iterator * appropriate to the UISelectItem(s) value. *

*/ private void initializeItems(Object kid) { if (kid instanceof UISelectItem) { UISelectItem ui = (UISelectItem) kid; SelectItem item = (SelectItem) ui.getValue(); if (item == null) { item = new SelectItem(ui.getItemValue(), ui.getItemLabel(), ui.getItemDescription(), ui.isItemDisabled(), ui.isItemEscaped(), ui.isNoSelectionOption()); } updateSingeItemIterator(item); items = singleItemIterator; } else if (kid instanceof UISelectItems) { UISelectItems ui = (UISelectItems) kid; Object value = ui.getValue(); if (value != null) { if (value instanceof SelectItem) { updateSingeItemIterator((SelectItem) value); items = singleItemIterator; } else if (value.getClass().isArray()) { items = new ArrayIterator(ctx, (UISelectItems) kid, value); } else if (value instanceof Iterable) { items = new IterableItemIterator(ctx, (UISelectItems) kid, (Iterable) value); } else if (value instanceof Map) { items = new MapIterator((Map) value); } else { throw new IllegalArgumentException(); } } if (items != null && !items.hasNext()) { items = null; } } } /** * @return the next valid child for processing */ private Object findNextValidChild() { if (kids.hasNext()) { Object next = kids.next(); while (kids.hasNext() && !(next instanceof UISelectItem || next instanceof UISelectItems)) { next = kids.next(); } if (next instanceof UISelectItem || next instanceof UISelectItems) { return next; } } return null; } /** * Update the singleItemIterator with the provided item * * @param item the {@link SelectItem} to expose as an Iterator */ private void updateSingeItemIterator(SelectItem item) { if (singleItemIterator == null) { singleItemIterator = new SingleElementIterator(); } singleItemIterator.updateItem(item); } // ---------------------------------------------------------- Nested Classes /** * Exposes single {@link SelectItem} instances as an Iterator. */ private static final class SingleElementIterator implements Iterator { private SelectItem item; private boolean nextCalled; // ----------------------------------------------- Methods from Iterator @Override public boolean hasNext() { return !nextCalled; } @Override public SelectItem next() { if (nextCalled) { throw new NoSuchElementException(); } nextCalled = true; return item; } @Override public void remove() { throw new UnsupportedOperationException(); } // ----------------------------------------------------- Private Methods private void updateItem(SelectItem item) { this.item = item; nextCalled = false; } } // END SingleElementIterator /** * Iterates over a Map of values exposing each entry as a SelectItem. Note that * this will do so re-using the same SelectItem but changing the value and label as appropriate. */ private static final class MapIterator implements Iterator { private SelectItem item = new SelectItem(); private Iterator iterator; // -------------------------------------------------------- Constructors private MapIterator(Map map) { this.iterator = map.entrySet().iterator(); } // ----------------------------------------------- Methods from Iterator @Override public boolean hasNext() { return iterator.hasNext(); } @Override public SelectItem next() { Map.Entry entry = (Map.Entry) iterator.next(); Object key = entry.getKey(); Object value = entry.getValue(); item.setLabel(((key != null) ? key.toString() : value.toString())); item.setValue(((value != null) ? value : "")); return item; } @Override public void remove() { throw new UnsupportedOperationException(); } } // END MapIterator /** *

* Base class to support iterating over Collections or Arrays that may or may not contain * SelectItem instances. *

*/ private static abstract class GenericObjectSelectItemIterator implements Iterator { /** * SelectItem that is updated based on the current Object being iterated over. */ private GenericObjectSelectItem genericObjectSI; /** * The source UISelectItems. */ protected UISelectItems sourceComponent; // -------------------------------------------------------- Constructors protected GenericObjectSelectItemIterator(UISelectItems sourceComponent) { this.sourceComponent = sourceComponent; } // --------------------------------------------------- Protected Methods protected SelectItem getSelectItemFor(FacesContext ctx, Object value) { if (genericObjectSI == null) { genericObjectSI = new GenericObjectSelectItem(sourceComponent); } genericObjectSI.updateItem(ctx, value); return genericObjectSI; } // ------------------------------------------------------ Nested Classes /** * A SelectItem implementation to support generating unique * SelectItem values based on ValueExpressions from the owning * {@link UISelectItems} instance. */ @SuppressWarnings({ "serial" }) private static final class GenericObjectSelectItem extends SelectItem { private static final String VAR = "var"; private static final String ITEM_VALUE = "itemValue"; private static final String ITEM_LABEL = "itemLabel"; private static final String ITEM_DESCRIPTION = "itemDescription"; private static final String ITEM_ESCAPED = "itemLabelEscaped"; private static final String ITEM_DISABLED = "itemDisabled"; private static final String NO_SELECTION_OPTION = "noSelectionOption"; /** * Resolves to the value of the SelectItem. */ private ValueExpression itemValue; /** * Resolves to the label of the SelectItem. */ private ValueExpression itemLabel; /** * Resolves to the description of the SelectItem. */ private ValueExpression itemDescription; /** * Determines the value for the escaped property of the SelectItem. */ private ValueExpression itemEscaped; /** * Determines the value for the disabled property of the SelectItem/ */ private ValueExpression itemDisabled; /** * Determines the value for the noSelectionOption property of the * SelectItem/ */ private ValueExpression noSelectionOption; /** * The request-scoped variable under which the current object will be exposed. */ private String var; private UISelectItems sourceComponent; // -------------------------------------------------------- Constructors private GenericObjectSelectItem(UISelectItems sourceComponent) { var = (String) sourceComponent.getAttributes().get(VAR); this.sourceComponent = sourceComponent; // itemValue = sourceComponent.getValueExpression(ITEM_VALUE); // itemLabel = sourceComponent.getValueExpression(ITEM_LABEL); // itemDescription = sourceComponent.getValueExpression(ITEM_DESCRIPTION); // itemEscaped = sourceComponent.getValueExpression(ITEM_ESCAPED); // itemDisabled = sourceComponent.getValueExpression(ITEM_DISABLED); // noSelectionOption = sourceComponent.getValueExpression(NO_SELECTION_OPTION); } // ----------------------------------------------------- Private Methods /** * Updates the SelectItem properties based on the current value. * * @param ctx the {@link FacesContext} for the current request * @param value the value to build the updated values from */ private void updateItem(FacesContext ctx, Object value) { Map reqMap = ctx.getExternalContext().getRequestMap(); Object oldVarValue = null; if (var != null) { oldVarValue = reqMap.put(var, value); } try { Map attrs = sourceComponent.getAttributes(); Object itemValueResult = attrs.get(ITEM_VALUE); Object itemLabelResult = attrs.get(ITEM_LABEL); Object itemDescriptionResult = attrs.get(ITEM_DESCRIPTION); Object itemEscapedResult = attrs.get(ITEM_ESCAPED); Object itemDisabledResult = attrs.get(ITEM_DISABLED); Object noSelectionOptionResult = attrs.get(NO_SELECTION_OPTION); setValue(((itemValueResult != null) ? itemValueResult : value)); setLabel(((itemLabelResult != null) ? itemLabelResult.toString() : value.toString())); setDescription(((itemDescriptionResult != null) ? itemDescriptionResult.toString() : null)); setEscape(((itemEscapedResult != null) ? Boolean.valueOf(itemEscapedResult.toString()) : true)); setDisabled(((itemDisabledResult != null) ? Boolean.valueOf(itemDisabledResult.toString()) : false)); setNoSelectionOption(((noSelectionOptionResult != null) ? Boolean.valueOf(noSelectionOptionResult.toString()) : false)); } finally { if (var != null) { if (oldVarValue != null) { reqMap.put(var, oldVarValue); } else { reqMap.remove(var); } } } } // --------------------------------------- Methods from Serializable private void writeObject(ObjectOutputStream out) throws IOException { throw new NotSerializableException(); } private void readObject(ObjectInputStream in) throws IOException { throw new NotSerializableException(); } } // END GenericObjectSelectItem } // END GenericObjectSelectItemIterator /** * Handles arrays of SelectItems, generic Objects, or combintations of both. * * A single GenericObjectSelectItem will be leverage for any * non-SelectItem objects encountered. */ private static final class ArrayIterator extends GenericObjectSelectItemIterator { private FacesContext ctx; private Object array; private int count; private int index; // -------------------------------------------------------- Constructors private ArrayIterator(FacesContext ctx, UISelectItems sourceComponent, Object array) { super(sourceComponent); this.ctx = ctx; this.array = array; count = Array.getLength(array); } // ----------------------------------------------- Methods from Iterator @Override public boolean hasNext() { return (index < count); } @Override public SelectItem next() { if (index >= count) { throw new NoSuchElementException(); } Object item = Array.get(array, index++); if (item instanceof SelectItem) { return (SelectItem) item; } else { return getSelectItemFor(ctx, item); } } @Override public void remove() { throw new UnsupportedOperationException(); } } // END ArrayIterator /** * Handles Collections of SelectItems, generic Objects, or combintations of both. * * A single GenericObjectSelectItem will be leverage for any * non-SelectItem objects encountered. */ private static final class IterableItemIterator extends GenericObjectSelectItemIterator { private FacesContext ctx; private Iterator iterator; // -------------------------------------------------------- Constructors private IterableItemIterator(FacesContext ctx, UISelectItems sourceComponent, Iterable iterable) { super(sourceComponent); this.ctx = ctx; this.iterator = iterable.iterator(); } // ----------------------------------------------- Methods from Iterator @Override public boolean hasNext() { return iterator.hasNext(); } @Override public SelectItem next() { Object item = iterator.next(); if (item instanceof SelectItem) { return (SelectItem) item; } else { return getSelectItemFor(ctx, item); } } @Override public void remove() { throw new UnsupportedOperationException(); } } // END CollectionItemIterator }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy