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 javax.faces.component;
017:
018: import java.util.*;
019: import javax.faces.el.ValueBinding;
020: import javax.faces.model.SelectItem;
021:
022: /**
023: * @author Mathias Broekelmann (latest modification by $Author: mbr $)
024: * @version $Revision: 511124 $ $Date: 2007-02-23 22:56:42 +0100 (Fr, 23 Feb 2007) $
025: */
026: class _SelectItemsIterator implements Iterator {
027: private final Iterator _childs;
028: private Iterator<SelectItem> _nestedItems;
029: private Object _nextItem;
030: private String _collectionLabel;
031: private UISelectItems _currentUISelectItems;
032:
033: public _SelectItemsIterator(UIComponent selectItemsParent) {
034: _childs = selectItemsParent.getChildren().iterator();
035: }
036:
037: public boolean hasNext() {
038: if (_nextItem != null) {
039: return true;
040: }
041: if (_nestedItems != null) {
042: if (_nestedItems.hasNext()) {
043: return true;
044: }
045: _nestedItems = null;
046: }
047: if (_childs.hasNext()) {
048: UIComponent child = (UIComponent) _childs.next();
049: if (child instanceof UISelectItem) {
050: UISelectItem uiSelectItem = (UISelectItem) child;
051: Object item = uiSelectItem.getValue();
052: if (item == null) {
053: Object itemValue = ((UISelectItem) child)
054: .getItemValue();
055: String label = ((UISelectItem) child)
056: .getItemLabel();
057: String description = ((UISelectItem) child)
058: .getItemDescription();
059: boolean disabled = ((UISelectItem) child)
060: .isItemDisabled();
061: if (label == null) {
062: label = itemValue.toString();
063: }
064: item = new SelectItem(itemValue, label,
065: description, disabled);
066: } else if (!(item instanceof SelectItem)) {
067: ValueBinding binding = ((UISelectItem) child)
068: .getValueBinding("value");
069: throw new IllegalArgumentException(
070: "Value binding '"
071: + (binding == null ? null : binding
072: .getExpressionString())
073: + "' of UISelectItem : "
074: + getPathToComponent(child)
075: + " does not reference an Object of type SelectItem");
076: }
077: _nextItem = item;
078: return true;
079: } else if (child instanceof UISelectItems) {
080: _currentUISelectItems = ((UISelectItems) child);
081: Object value = _currentUISelectItems.getValue();
082:
083: if (value instanceof SelectItem) {
084: _nextItem = value;
085: return true;
086: } else if (value instanceof SelectItem[]) {
087: _nestedItems = Arrays.asList((SelectItem[]) value)
088: .iterator();
089: _collectionLabel = "Array";
090: return hasNext();
091: } else if (value instanceof Collection) {
092: _nestedItems = ((Collection<SelectItem>) value)
093: .iterator();
094: _collectionLabel = "Collection";
095: return hasNext();
096: } else if (value instanceof Map) {
097: Map map = ((Map) value);
098: Collection<SelectItem> items = new ArrayList<SelectItem>(
099: map.size());
100: for (Iterator it = map.entrySet().iterator(); it
101: .hasNext();) {
102: Map.Entry entry = (Map.Entry) it.next();
103: items.add(new SelectItem(entry.getValue(),
104: entry.getKey().toString()));
105: }
106: _nestedItems = items.iterator();
107: _collectionLabel = "Map";
108: return hasNext();
109: } else {
110: ValueBinding binding = _currentUISelectItems
111: .getValueBinding("value");
112:
113: throw new IllegalArgumentException(
114: "Value binding '"
115: + (binding == null ? null : binding
116: .getExpressionString())
117: + "'of UISelectItems with component-path "
118: + getPathToComponent(child)
119: + " does not reference an Object of type SelectItem, SelectItem[], Collection or Map but of type : "
120: + ((value == null) ? null : value
121: .getClass().getName()));
122: }
123: } else {
124: //todo: may other objects than selectItems be nested or not?
125: //log.error("Invalid component : " + getPathToComponent(child) + " : must be UISelectItem or UISelectItems, is of type : "+((child==null)?"null":child.getClass().getName()));
126: }
127: }
128: return false;
129: }
130:
131: public Object next() {
132: if (!hasNext()) {
133: throw new NoSuchElementException();
134: }
135: if (_nextItem != null) {
136: Object value = _nextItem;
137: _nextItem = null;
138: return value;
139: }
140: if (_nestedItems != null) {
141: Object item = _nestedItems.next();
142: if (!(item instanceof SelectItem)) {
143: ValueBinding binding = _currentUISelectItems
144: .getValueBinding("value");
145: throw new IllegalArgumentException(
146: _collectionLabel
147: + " referenced by UISelectItems with binding '"
148: + binding.getExpressionString()
149: + "' and Component-Path : "
150: + getPathToComponent(_currentUISelectItems)
151: + " does not contain Objects of type SelectItem");
152: }
153: return item;
154: }
155: throw new NoSuchElementException();
156: }
157:
158: public void remove() {
159: throw new UnsupportedOperationException();
160: }
161:
162: private String getPathToComponent(UIComponent component) {
163: StringBuffer buf = new StringBuffer();
164:
165: if (component == null) {
166: buf.append("{Component-Path : ");
167: buf.append("[null]}");
168: return buf.toString();
169: }
170:
171: getPathToComponent(component, buf);
172:
173: buf.insert(0, "{Component-Path : ");
174: buf.append("}");
175:
176: return buf.toString();
177: }
178:
179: private void getPathToComponent(UIComponent component,
180: StringBuffer buf) {
181: if (component == null)
182: return;
183:
184: StringBuffer intBuf = new StringBuffer();
185:
186: intBuf.append("[Class: ");
187: intBuf.append(component.getClass().getName());
188: if (component instanceof UIViewRoot) {
189: intBuf.append(",ViewId: ");
190: intBuf.append(((UIViewRoot) component).getViewId());
191: } else {
192: intBuf.append(",Id: ");
193: intBuf.append(component.getId());
194: }
195: intBuf.append("]");
196:
197: buf.insert(0, intBuf);
198:
199: if (component != null) {
200: getPathToComponent(component.getParent(), buf);
201: }
202: }
203: }
|