1 33 34 package com.icesoft.faces.renderkit.dom_html_basic; 35 36 import com.icesoft.faces.context.DOMContext; 37 import com.icesoft.faces.context.effects.JavascriptContext; 38 import org.w3c.dom.Document ; 39 import org.w3c.dom.Element ; 40 import org.w3c.dom.Text ; 41 import org.apache.commons.logging.LogFactory; 42 43 import javax.faces.component.*; 44 import javax.faces.component.html.HtmlSelectManyCheckbox; 45 import javax.faces.context.FacesContext; 46 import javax.faces.convert.Converter; 47 import javax.faces.convert.ConverterException; 48 import javax.faces.el.ValueBinding; 49 import javax.faces.model.SelectItem; 50 import javax.faces.model.SelectItemGroup; 51 import java.io.IOException ; 52 import java.lang.reflect.Array ; 53 import java.util.*; 54 import java.util.logging.Logger ; 55 import java.util.logging.Level ; 56 57 public class MenuRenderer extends DomBasicInputRenderer { 58 59 private static Logger log = Logger.getLogger(MenuRenderer.class.getName()); 60 61 public void decode(FacesContext facesContext, UIComponent uiComponent) { 62 validateParameters(facesContext, uiComponent, null); 63 if (isStatic(uiComponent)) { 64 return; 65 } 66 String clientId = uiComponent.getClientId(facesContext); 67 if (uiComponent instanceof UISelectMany) { 68 Map requestParameterValuesMap = facesContext.getExternalContext() 69 .getRequestParameterValuesMap(); 70 if (requestParameterValuesMap.containsKey(clientId)) { 71 String [] decodedValue = 72 (String []) requestParameterValuesMap.get(clientId); 73 setSubmittedValue(uiComponent, decodedValue); 74 } else { 75 setSubmittedValue(uiComponent, new String [0]); 77 } 78 } else if (uiComponent instanceof UISelectOne) { 79 Map requestParameterValuesMap = facesContext.getExternalContext() 80 .getRequestParameterValuesMap(); 81 String decodedValue = null; 82 if ((requestParameterValuesMap != null) && (requestParameterValuesMap.containsKey(clientId))) { 83 decodedValue = 84 ((String []) requestParameterValuesMap.get(clientId))[0] 85 .trim(); 86 } else { 87 decodedValue = ""; 90 } 91 ((UISelectOne) uiComponent).setSubmittedValue(decodedValue); 92 93 } 94 return; 95 } 96 97 public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) 98 throws IOException { 99 validateParameters(facesContext, uiComponent, null); 100 } 101 102 public void encodeChildren(FacesContext facesContext, 103 UIComponent uiComponent) { 104 validateParameters(facesContext, uiComponent, null); 105 } 106 107 public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) 108 throws IOException { 109 validateParameters(facesContext, uiComponent, null); 110 111 renderSelect(facesContext, uiComponent); 112 JavascriptContext.fireEffect(uiComponent, facesContext); 113 } 114 115 public Object getConvertedValue(FacesContext facesContext, 116 UIComponent uiComponent, 117 Object newSubmittedValue) 118 throws ConverterException { 119 if (uiComponent instanceof UISelectOne) { 120 if (newSubmittedValue == null || "".equals(newSubmittedValue)) { 121 return null; 122 } else { 123 return super.getConvertedValue(facesContext, 124 (UISelectOne) uiComponent, 125 newSubmittedValue); 126 } 127 } else { 128 return convertSelectValue(facesContext, 129 ((UISelectMany) uiComponent), 130 (String []) newSubmittedValue); 131 } 132 } 133 134 public Object convertSelectValue(FacesContext facesContext, 135 UIComponent uiComponent, 136 Object newSubmittedValue) 137 throws ConverterException { 138 if (uiComponent instanceof UISelectOne) { 139 if (newSubmittedValue == null || "".equals(newSubmittedValue)) { 140 return null; 141 } else { 142 return super.getConvertedValue(facesContext, 143 (UISelectOne) uiComponent, 144 newSubmittedValue); 145 } 146 } else { 147 return convertSelectValue(facesContext, 148 ((UISelectMany) uiComponent), 149 (String []) newSubmittedValue); 150 } 151 } 152 153 public Object convertSelectValue(FacesContext facesContext, 154 UISelectMany uiSelectMany, 155 String [] newSubmittedValues) 156 throws ConverterException { 157 158 ValueBinding valueBinding = uiSelectMany.getValueBinding("value"); 159 if (valueBinding == null) { 160 Class componentType = (new Object [1]).getClass().getComponentType(); 161 return convertArray(facesContext, uiSelectMany, componentType, 162 newSubmittedValues); 163 } 164 Class valueBindingClass = valueBinding.getType(facesContext); 165 if (valueBindingClass == null) { 166 throw new ConverterException("Inconvertible type in value binding"); 167 } 168 if (List.class.isAssignableFrom(valueBindingClass)) { 169 ArrayList submittedValuesAsList = new ArrayList( 170 newSubmittedValues.length); 171 for (int index = 0; index < newSubmittedValues.length; index++) { 172 submittedValuesAsList.add(newSubmittedValues[index]); 173 } 174 return submittedValuesAsList; 175 } 176 if (valueBindingClass.isArray()) { 177 Class componentType = valueBindingClass.getComponentType(); 178 return convertArray(facesContext, uiSelectMany, componentType, 179 newSubmittedValues); 180 } 181 throw new ConverterException( 182 "Non-list and Non-array values are inconvertible"); 183 } 184 185 protected Object convertArray(FacesContext facesContext, 186 UISelectMany uiSelectMany, 187 Class componentType, 188 String [] newSubmittedValues) 189 throws ConverterException { 190 191 if (componentType.equals(String .class)) { 193 return newSubmittedValues; 194 } 195 196 if (newSubmittedValues == null) { 198 return Array.newInstance(componentType, 0); 199 } 200 201 int numberOfValues = newSubmittedValues.length; 203 Object convertedValues = Array.newInstance(componentType, 204 numberOfValues); 205 206 Converter converter = uiSelectMany.getConverter(); 208 if (converter == null) { 209 converter = getConverterForClass(componentType); 211 } 212 if (converter == null) { 213 if (componentType.equals(Object .class)) { 215 return newSubmittedValues; 216 } else { 217 throw new ConverterException("Converter is null"); 218 } 219 } 220 221 for (int index = 0; index < numberOfValues; index++) { 222 223 Object nextConvertedElement = converter.getAsObject(facesContext, 225 uiSelectMany, 226 newSubmittedValues[index]); 227 228 if (!componentType.isPrimitive()) { 229 Array.set(convertedValues, index, nextConvertedElement); 230 } else if (componentType.equals(Boolean.TYPE)) { 231 232 Array.setBoolean(convertedValues, index, 233 ((Boolean ) nextConvertedElement).booleanValue()); 234 235 } else if (componentType.equals(Integer.TYPE)) { 236 237 Array.setInt(convertedValues, index, 238 ((Integer ) nextConvertedElement).intValue()); 239 240 } else if (componentType.equals(Long.TYPE)) { 241 242 Array.setLong(convertedValues, index, 243 ((Long ) nextConvertedElement).longValue()); 244 245 } else if (componentType.equals(Short.TYPE)) { 246 247 Array.setShort(convertedValues, index, 248 ((Short ) nextConvertedElement).shortValue()); 249 250 } else if (componentType.equals(Byte.TYPE)) { 251 252 Array.setByte(convertedValues, index, 253 ((Byte ) nextConvertedElement).byteValue()); 254 255 } else if (componentType.equals(Float.TYPE)) { 256 257 Array.setFloat(convertedValues, index, 258 ((Float ) nextConvertedElement).floatValue()); 259 260 } else if (componentType.equals(Double.TYPE)) { 261 262 Array.setDouble(convertedValues, index, 263 ((Double ) nextConvertedElement).doubleValue()); 264 265 } else if (componentType.equals(Character.TYPE)) { 266 267 Array.setChar(convertedValues, index, 268 ((Character ) nextConvertedElement).charValue()); 269 270 } 271 } 272 return convertedValues; 273 } 274 275 protected void renderOption(FacesContext facesContext, 276 UIComponent uiComponent, 277 SelectItem selectItem, Element optionGroup) 278 throws IOException { 279 280 DOMContext domContext = 281 DOMContext.attachDOMContext(facesContext, uiComponent); 282 283 Element select = (Element ) domContext.getRootNode(); 284 Element option = domContext.createElement("option"); 285 286 if (optionGroup == null) { 287 select.appendChild(option); 288 } else { 289 optionGroup.appendChild(option); 290 } 291 292 String valueString = formatComponentValue(facesContext, uiComponent, 293 selectItem.getValue()); 294 option.setAttribute("value", valueString); 295 296 Object submittedValues[] = 297 getSubmittedSelectedValues(uiComponent); 298 boolean isSelected; 299 if (submittedValues != null) { 300 isSelected = isSelected(valueString, submittedValues); 301 } else { 302 Object selectedValues = 303 getCurrentSelectedValues(uiComponent); 304 isSelected = isSelected(selectItem.getValue(), selectedValues); 305 } 306 307 if (isSelected) { 308 option.setAttribute("selected", "selected"); 309 } 310 if (selectItem.isDisabled()) { 311 option.setAttribute("disabled", "disabled"); 312 } 313 314 Document doc = domContext.getDocument(); 315 Text labelNode = doc.createTextNode(selectItem.getLabel()); 316 option.appendChild(labelNode); 317 } 318 319 void renderSelect(FacesContext facesContext, UIComponent uiComponent) 320 throws IOException { 321 HashSet excludes = new HashSet(); 322 DOMContext domContext = 324 DOMContext.attachDOMContext(facesContext, uiComponent); 325 if (!domContext.isInitialized()) { 326 Element root = domContext.createElement("select"); 327 domContext.setRootNode(root); 328 setRootElementId(facesContext, root, uiComponent); 329 root.setAttribute("name", uiComponent.getClientId(facesContext)); 330 String styleClass = null; 332 if (null != (styleClass = (String ) uiComponent.getAttributes().get( 333 "styleClass"))) { 334 root.setAttribute("class", styleClass); 335 } 336 if (!getMultipleText(uiComponent).equals("")) { 337 root.setAttribute("multiple", Boolean.TRUE.toString()); 338 } 339 } 340 Element root = (Element ) domContext.getRootNode(); 341 342 int itemCount = countSelectOptionsRecursive(facesContext, uiComponent); 346 Object size = uiComponent.getAttributes().get("size"); 348 if ((null == size) 349 || ( ( size instanceof Integer ) && 350 ( ((Integer ) size).intValue() == Integer.MIN_VALUE || 351 ((Integer ) size).intValue() == 0) ) ) { 352 renderSizeAttribute(root, itemCount); 353 excludes.add("size"); 354 } 355 356 Object currentValue = null; 357 if (null == 358 (currentValue = ((UIInput) uiComponent).getSubmittedValue())) { 359 currentValue = ""; 360 } 361 362 addJavaScript(facesContext, uiComponent, root, currentValue.toString(), 363 excludes); 364 365 PassThruAttributeRenderer.renderAttributes(facesContext, uiComponent, 366 getExcludesArray(excludes)); 367 excludes.clear(); 368 369 domContext.stepInto(uiComponent); 370 renderOptions(facesContext, uiComponent); 371 domContext.stepOver(); 372 domContext.streamWrite(facesContext, uiComponent); 373 374 } 375 376 public String getEventType(UIComponent uiComponent) { 377 if (uiComponent instanceof javax.faces.component.html.HtmlSelectOneListbox) 378 { 379 return "onchange"; 380 } else 381 if (uiComponent instanceof javax.faces.component.html.HtmlSelectOneMenu) 382 { 383 return "onchange"; 384 } else 385 if (uiComponent instanceof javax.faces.component.html.HtmlSelectManyListbox) 386 { 387 return "onchange"; 388 } else 389 if (uiComponent instanceof javax.faces.component.html.HtmlSelectManyMenu) 390 { 391 return "onchange"; 392 } else if (uiComponent instanceof HtmlSelectManyCheckbox) { 393 return "onclick"; 394 } 395 return ""; 396 } 397 398 int countSelectOptionsRecursive(FacesContext facesContext, 399 UIComponent uiComponent) { 400 int counter = 0; 401 Iterator selectItems = getSelectItems(uiComponent); 402 while (selectItems.hasNext()) { 403 counter++; 404 SelectItem nextSelectItem = (SelectItem) selectItems.next(); 405 if (nextSelectItem instanceof SelectItemGroup) { 406 counter += ((SelectItemGroup) nextSelectItem) 407 .getSelectItems().length; 408 } 409 } 410 return counter; 411 } 412 413 void renderOptions(FacesContext facesContext, UIComponent uiComponent) 414 throws IOException { 415 416 DOMContext domContext = 417 DOMContext.attachDOMContext(facesContext, uiComponent); 418 419 Element rootSelectElement = (Element ) domContext.getRootNode(); 420 DOMContext.removeChildrenByTagName(rootSelectElement, "option"); 421 DOMContext.removeChildrenByTagName(rootSelectElement, "optgroup"); 422 423 Iterator selectItems = getSelectItems(uiComponent); 424 while (selectItems.hasNext()) { 425 SelectItem nextSelectItem = (SelectItem) selectItems.next(); 426 if (nextSelectItem instanceof SelectItemGroup) { 427 Element optGroup = domContext.createElement("optgroup"); 428 rootSelectElement.appendChild(optGroup); 429 optGroup.setAttribute("label", nextSelectItem.getLabel()); 430 domContext.setCursorParent(optGroup); 431 SelectItem[] selectItemsArray = 432 ((SelectItemGroup) nextSelectItem).getSelectItems(); 433 for (int i = 0; i < selectItemsArray.length; ++i) { 434 renderOption(facesContext, uiComponent, selectItemsArray[i], 435 optGroup); 436 } 437 } else { 438 renderOption(facesContext, uiComponent, nextSelectItem, null); 439 } 440 } 441 } 442 443 boolean isSelected(Object sentinel, Object selectedValues) { 444 boolean isSelected = false; 445 if (selectedValues == null || sentinel == null) { 446 return isSelected; 447 } 448 int length = Array.getLength(selectedValues); 449 for (int index = 0; index < length; index++) { 450 Object nextSelectedValue = Array.get(selectedValues, index); 451 if (nextSelectedValue == null && sentinel == null) { 452 isSelected = true; 453 break; 454 } else if (sentinel.equals(nextSelectedValue)) { 455 isSelected = true; 456 break; 457 }else if (sentinel instanceof String ) { 458 if (isConversionMatched(sentinel.toString(), nextSelectedValue)) { 459 isSelected = true; 460 break; 461 } 462 } 463 } 464 return isSelected; 465 } 466 467 boolean isSelected(Object sentinelValue, Object [] selectedValues) { 468 boolean valueIsSelected = false; 469 if (selectedValues != null) { 470 Iterator selectedValuesIterator = 471 Arrays.asList(selectedValues).iterator(); 472 while (selectedValuesIterator.hasNext()) { 473 if (selectedValuesIterator.next().equals(sentinelValue)) { 474 valueIsSelected = true; 475 break; 476 } 477 } 478 } 479 return valueIsSelected; 480 } 481 482 489 protected void renderSizeAttribute(Element targetElement, int size) 490 throws IOException { 491 targetElement.setAttribute("size", "1"); 492 } 493 494 String getSelectedTextString() { 495 return " selected"; 496 } 497 498 public String getMultipleText(UIComponent component) { 501 if (component instanceof UISelectMany) { 502 return " multiple "; 503 } 504 return ""; 505 } 506 507 Object [] getSubmittedSelectedValues(UIComponent uiComponent) { 508 if (uiComponent instanceof UISelectMany) { 509 UISelectMany uiSelectMany = (UISelectMany) uiComponent; 510 return (Object []) uiSelectMany.getSubmittedValue(); 511 } 512 if (uiComponent instanceof UISelectOne) { 513 UISelectOne uiSelectOne = (UISelectOne) uiComponent; 514 Object submittedValue = uiSelectOne.getSubmittedValue(); 515 if (submittedValue != null) { 516 return new Object []{submittedValue}; 517 } 518 } 519 return null; 520 } 521 522 523 Object getCurrentSelectedValues(UIComponent uiComponent) { 524 Object currentSelectedValues = null; 525 if (uiComponent instanceof UISelectMany) { 526 UISelectMany uiSelectMany = (UISelectMany) uiComponent; 527 currentSelectedValues = uiSelectMany.getValue(); 528 if (currentSelectedValues instanceof List) { 529 return ((List) currentSelectedValues).toArray(); 530 } 531 return currentSelectedValues; 532 } 533 if (uiComponent instanceof UISelectOne) { 534 UISelectOne uiSelectOne = (UISelectOne) uiComponent; 535 currentSelectedValues = uiSelectOne.getValue(); 536 if (currentSelectedValues != null) { 537 return new Object []{currentSelectedValues}; 538 } 539 } 540 return null; 541 } 542 543 protected Iterator getSelectItems(UIComponent uiComponent) { 544 545 List selectItems = new ArrayList(); 546 Iterator children = uiComponent.getChildren().iterator(); 547 548 while (children.hasNext()) { 549 UIComponent nextSelectItemChild = (UIComponent) children.next(); 550 if (nextSelectItemChild instanceof UISelectItem) { 551 Object selectItemValue = 552 ((UISelectItem) nextSelectItemChild).getValue(); 553 if (selectItemValue != null && 554 selectItemValue instanceof SelectItem) { 555 selectItems.add(selectItemValue); 556 } else { 557 assignDataIfNull(nextSelectItemChild); 562 selectItems.add( 563 new SelectItem( 564 ((UISelectItem) nextSelectItemChild).getItemValue(), 565 ((UISelectItem) nextSelectItemChild).getItemLabel(), 566 ((UISelectItem) nextSelectItemChild).getItemDescription(), 567 ((UISelectItem) nextSelectItemChild).isItemDisabled())); 568 } 569 } else if (nextSelectItemChild instanceof UISelectItems) { 570 Object selectItemsValue = 571 ((UISelectItems) nextSelectItemChild).getValue(); 572 573 if (selectItemsValue != null) { 574 if (selectItemsValue instanceof SelectItem) { 575 selectItems.add(selectItemsValue); 576 } else if (selectItemsValue instanceof Collection) { 577 Iterator selectItemsIterator = 578 ((Collection) selectItemsValue).iterator(); 579 while (selectItemsIterator.hasNext()) { 580 selectItems.add(selectItemsIterator.next()); 581 } 582 } else if (selectItemsValue instanceof SelectItem[]) { 583 SelectItem selectItemArray[] = 584 (SelectItem[]) selectItemsValue; 585 for (int i = 0; i < selectItemArray.length; i++) { 586 selectItems.add(selectItemArray[i]); 587 } 588 } else if (selectItemsValue instanceof Map) { 589 Iterator selectItemIterator = 590 ((Map) selectItemsValue).keySet().iterator(); 591 while (selectItemIterator.hasNext()) { 592 Object nextKey = selectItemIterator.next(); 593 if (nextKey != null) { 594 Object nextValue = 595 ((Map) selectItemsValue).get(nextKey); 596 if (nextValue != null) { 597 selectItems.add( 598 new SelectItem( 599 nextValue.toString(), 600 nextKey.toString())); 601 } 602 } 603 } 604 } else if (selectItemsValue instanceof String []) { 605 String stringItemArray[] = (String []) selectItemsValue; 606 for (int i = 0; i < stringItemArray.length; i++) { 607 selectItems.add(new SelectItem(stringItemArray[i])); 608 } 609 } 610 } 611 } 612 } 613 return selectItems.iterator(); 614 } 615 616 private void assignDataIfNull(Object selectItem) { 617 UISelectItem uiSelectItem = (UISelectItem) selectItem; 618 if (uiSelectItem.getItemValue() == null) { 619 if (uiSelectItem.getItemLabel() != null) { 620 uiSelectItem.setItemValue(uiSelectItem.getItemLabel()); 621 } 622 } 623 if (uiSelectItem.getItemLabel() == null) { 624 if (uiSelectItem.getItemValue() != null) { 625 uiSelectItem 626 .setItemLabel(uiSelectItem.getItemValue().toString()); 627 } 628 } 629 } 630 631 protected void addJavaScript(FacesContext facesContext, 632 UIComponent uiComponent, Element root, 633 String currentValue, 634 Set excludes) { 635 } 636 637 private boolean isConversionMatched(String sentinel, Object selectedValue){ 638 boolean match = false; 639 if (selectedValue instanceof Long ){ 640 if (selectedValue.equals(Long.valueOf(sentinel))) { 641 match = true; 642 } 643 } else if (selectedValue instanceof Byte ) { 644 if (selectedValue.equals(Byte.valueOf(sentinel))) { 645 match = true; 646 } 647 } else if (selectedValue instanceof Integer ) { 648 if (selectedValue.equals(Integer.valueOf(sentinel))) { 649 match = true; 650 } 651 } else if (selectedValue instanceof Short ) { 652 if (selectedValue.equals(Short.valueOf(sentinel))) { 653 match = true; 654 } 655 } else if (selectedValue instanceof Double ) { 656 if (selectedValue.equals(Double.valueOf(sentinel))) { 657 match = true; 658 } 659 } else if (selectedValue instanceof Float ) { 660 if (selectedValue.equals(Float.valueOf(sentinel))) { 661 match = true; 662 } 663 } else if (selectedValue instanceof Boolean ) { 664 if (selectedValue.equals(Boolean.valueOf(sentinel))) { 665 match = true; 666 } 667 } 668 return match; 669 } 670 } | Popular Tags |