001: /*
002: * Copyright 2005 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.myfaces.shared_impl.util;
017:
018: import java.util.ArrayList;
019: import java.util.Arrays;
020: import java.util.Collection;
021: import java.util.Iterator;
022: import java.util.Map;
023: import java.util.NoSuchElementException;
024:
025: import javax.faces.component.UIComponent;
026: import javax.faces.component.UISelectItem;
027: import javax.faces.component.UISelectItems;
028: import javax.faces.el.ValueBinding;
029: import javax.faces.model.SelectItem;
030:
031: import org.apache.myfaces.shared_impl.renderkit.RendererUtils;
032:
033: /**
034: * @author Mathias Broekelmann (latest modification by $Author$)
035: * @version $Revision$ $Date$
036: */
037: public class SelectItemsIterator implements Iterator {
038: private final Iterator _childs;
039: private Iterator _nestedItems;
040: private Object _nextItem;
041: private String _collectionLabel;
042: private UISelectItems _currentUISelectItems;
043:
044: public SelectItemsIterator(UIComponent selectItemsParent) {
045: _childs = selectItemsParent.getChildren().iterator();
046: }
047:
048: public boolean hasNext() {
049: if (_nextItem != null) {
050: return true;
051: }
052: if (_nestedItems != null) {
053: if (_nestedItems.hasNext()) {
054: return true;
055: }
056: _nestedItems = null;
057: }
058: if (_childs.hasNext()) {
059: UIComponent child = (UIComponent) _childs.next();
060: if (child instanceof UISelectItem) {
061: UISelectItem uiSelectItem = (UISelectItem) child;
062: Object item = uiSelectItem.getValue();
063: if (item == null) {
064: Object itemValue = ((UISelectItem) child)
065: .getItemValue();
066: String label = ((UISelectItem) child)
067: .getItemLabel();
068: String description = ((UISelectItem) child)
069: .getItemDescription();
070: boolean disabled = ((UISelectItem) child)
071: .isItemDisabled();
072: boolean escaped = ((UISelectItem) child)
073: .isItemEscaped();
074: if (label == null) {
075: label = itemValue.toString();
076: }
077: item = new SelectItem(itemValue, label,
078: description, disabled, escaped);
079: } else if (!(item instanceof SelectItem)) {
080: ValueBinding binding = ((UISelectItem) child)
081: .getValueBinding("value");
082: throw new IllegalArgumentException(
083: "Value binding '"
084: + (binding == null ? null : binding
085: .getExpressionString())
086: + "' of UISelectItem : "
087: + RendererUtils
088: .getPathToComponent(child)
089: + " does not reference an Object of type SelectItem");
090: }
091: _nextItem = item;
092: return true;
093: } else if (child instanceof UISelectItems) {
094: _currentUISelectItems = ((UISelectItems) child);
095: Object value = _currentUISelectItems.getValue();
096:
097: if (value instanceof SelectItem) {
098: _nextItem = value;
099: return true;
100: } else if (value instanceof SelectItem[]) {
101: _nestedItems = Arrays.asList((SelectItem[]) value)
102: .iterator();
103: _collectionLabel = "Array";
104: return hasNext();
105: } else if (value instanceof Collection) {
106: _nestedItems = ((Collection) value).iterator();
107: _collectionLabel = "Collection";
108: return hasNext();
109: } else if (value instanceof Map) {
110: Map map = ((Map) value);
111: Collection items = new ArrayList(map.size());
112: for (Iterator it = map.entrySet().iterator(); it
113: .hasNext();) {
114: Map.Entry entry = (Map.Entry) it.next();
115: items.add(new SelectItem(entry.getValue(),
116: entry.getKey().toString()));
117: }
118: _nestedItems = items.iterator();
119: _collectionLabel = "Map";
120: return hasNext();
121: } else {
122: ValueBinding binding = _currentUISelectItems
123: .getValueBinding("value");
124:
125: throw new IllegalArgumentException(
126: "Value binding '"
127: + (binding == null ? null : binding
128: .getExpressionString())
129: + "'of UISelectItems with component-path "
130: + RendererUtils
131: .getPathToComponent(child)
132: + " does not reference an Object of type SelectItem, SelectItem[], Collection or Map but of type : "
133: + ((value == null) ? null : value
134: .getClass().getName()));
135: }
136: } else {
137: //todo: may other objects than selectItems be nested or not?
138: //log.error("Invalid component : " + getPathToComponent(child) + " : must be UISelectItem or UISelectItems, is of type : "+((child==null)?"null":child.getClass().getName()));
139: }
140: }
141: return false;
142: }
143:
144: public Object next() {
145: if (!hasNext()) {
146: throw new NoSuchElementException();
147: }
148: if (_nextItem != null) {
149: Object value = _nextItem;
150: _nextItem = null;
151: return value;
152: }
153: if (_nestedItems != null) {
154: Object item = _nestedItems.next();
155: if (!(item instanceof SelectItem)) {
156: ValueBinding binding = _currentUISelectItems
157: .getValueBinding("value");
158: throw new IllegalArgumentException(
159: _collectionLabel
160: + " referenced by UISelectItems with binding '"
161: + binding.getExpressionString()
162: + "' and Component-Path : "
163: + RendererUtils
164: .getPathToComponent(_currentUISelectItems)
165: + " does not contain Objects of type SelectItem");
166: }
167: return item;
168: }
169: throw new NoSuchElementException();
170: }
171:
172: public void remove() {
173: throw new UnsupportedOperationException();
174: }
175: }
|