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