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 javax.faces.component;
17
18 import java.util;
19 import javax.faces.el.ValueBinding;
20 import javax.faces.model.SelectItem;
21
22
23 /**
24 * @author Mathias Broekelmann (latest modification by $Author: mbr $)
25 * @version $Revision: 279433 $ $Date: 2005-09-07 18:04:45 -0400 (Wed, 07 Sep 2005) $
26 */
27 class _SelectItemsIterator implements Iterator
28 {
29 private final Iterator _childs;
30 private Iterator _nestedItems;
31 private Object _nextItem;
32 private String _collectionLabel;
33 private UISelectItems _currentUISelectItems;
34
35 public _SelectItemsIterator(UIComponent selectItemsParent)
36 {
37 _childs = selectItemsParent.getChildren().iterator();
38 }
39
40 public boolean hasNext()
41 {
42 if(_nextItem != null)
43 {
44 return true;
45 }
46 if(_nestedItems != null)
47 {
48 if(_nestedItems.hasNext())
49 {
50 return true;
51 }
52 _nestedItems = null;
53 }
54 if (_childs.hasNext())
55 {
56 UIComponent child = (UIComponent) _childs.next();
57 if (child instanceof UISelectItem)
58 {
59 UISelectItem uiSelectItem = (UISelectItem) child;
60 Object item = uiSelectItem.getValue();
61 if (item == null)
62 {
63 Object itemValue = ((UISelectItem) child).getItemValue();
64 String label = ((UISelectItem) child).getItemLabel();
65 String description = ((UISelectItem) child)
66 .getItemDescription();
67 boolean disabled = ((UISelectItem) child).isItemDisabled();
68 if (label == null)
69 {
70 label = itemValue.toString();
71 }
72 item = new SelectItem(itemValue, label, description,
73 disabled);
74 }
75 else if (!(item instanceof SelectItem))
76 {
77 ValueBinding binding = ((UISelectItem) child)
78 .getValueBinding("value");
79 throw new IllegalArgumentException(
80 "Value binding '"
81 + (binding == null ? null : binding.getExpressionString())
82 + "' of UISelectItem : "
83 + getPathToComponent(child)
84 + " does not reference an Object of type SelectItem");
85 }
86 _nextItem = item;
87 return true;
88 }
89 else if (child instanceof UISelectItems)
90 {
91 _currentUISelectItems = ((UISelectItems) child);
92 Object value = _currentUISelectItems.getValue();
93
94 if (value instanceof SelectItem)
95 {
96 _nextItem = value;
97 return true;
98 }
99 else if (value instanceof SelectItem[])
100 {
101 _nestedItems = Arrays.asList((SelectItem[]) value)
102 .iterator();
103 _collectionLabel = "Array";
104 return hasNext();
105 }
106 else if (value instanceof Collection)
107 {
108 _nestedItems = ((Collection)value).iterator();
109 _collectionLabel = "Collection";
110 return hasNext();
111 }
112 else if (value instanceof Map)
113 {
114 Map map = ((Map) value);
115 Collection items = new ArrayList(map.size());
116 for (Iterator it = map.entrySet().iterator(); it
117 .hasNext();)
118 {
119 Map.Entry entry = (Map.Entry) it.next();
120 items.add(new SelectItem(entry.getValue(), entry
121 .getKey().toString()));
122 }
123 _nestedItems = items.iterator();
124 _collectionLabel = "Map";
125 return hasNext();
126 }
127 else
128 {
129 ValueBinding binding = _currentUISelectItems.getValueBinding("value");
130
131 throw new IllegalArgumentException(
132 "Value binding '"
133 + (binding == null ? null : binding
134 .getExpressionString())
135 + "'of UISelectItems with component-path "
136 + getPathToComponent(child)
137 + " does not reference an Object of type SelectItem, SelectItem[], Collection or Map but of type : "
138 + ((value == null) ? null : value
139 .getClass()
140 .getName()));
141 }
142 }
143 else
144 {
145 //todo: may other objects than selectItems be nested or not?
146 //log.error("Invalid component : " + getPathToComponent(child) + " : must be UISelectItem or UISelectItems, is of type : "+((child==null)?"null":child.getClass().getName()));
147 }
148 }
149 return false;
150 }
151
152 public Object next()
153 {
154 if (!hasNext())
155 {
156 throw new NoSuchElementException();
157 }
158 if(_nextItem != null)
159 {
160 Object value = _nextItem;
161 _nextItem = null;
162 return value;
163 }
164 if (_nestedItems != null)
165 {
166 Object item = _nestedItems.next();
167 if (!(item instanceof SelectItem))
168 {
169 ValueBinding binding = _currentUISelectItems
170 .getValueBinding("value");
171 throw new IllegalArgumentException(
172 _collectionLabel + " referenced by UISelectItems with binding '"
173 + binding.getExpressionString()
174 + "' and Component-Path : " + getPathToComponent(_currentUISelectItems)
175 + " does not contain Objects of type SelectItem");
176 }
177 return item;
178 }
179 throw new NoSuchElementException();
180 }
181
182 public void remove()
183 {
184 throw new UnsupportedOperationException();
185 }
186
187
188 private String getPathToComponent(UIComponent component)
189 {
190 StringBuffer buf = new StringBuffer();
191
192 if(component == null)
193 {
194 buf.append("{Component-Path : ");
195 buf.append("[null]}");
196 return buf.toString();
197 }
198
199 getPathToComponent(component,buf);
200
201 buf.insert(0,"{Component-Path : ");
202 buf.append("}");
203
204 return buf.toString();
205 }
206
207 private void getPathToComponent(UIComponent component, StringBuffer buf)
208 {
209 if(component == null)
210 return;
211
212 StringBuffer intBuf = new StringBuffer();
213
214 intBuf.append("[Class: ");
215 intBuf.append(component.getClass().getName());
216 if(component instanceof UIViewRoot)
217 {
218 intBuf.append(",ViewId: ");
219 intBuf.append(((UIViewRoot) component).getViewId());
220 }
221 else
222 {
223 intBuf.append(",Id: ");
224 intBuf.append(component.getId());
225 }
226 intBuf.append("]");
227
228 buf.insert(0,intBuf);
229
230 if(component!=null)
231 {
232 getPathToComponent(component.getParent(),buf);
233 }
234 }
235 }