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 }