1 16 package org.apache.myfaces.renderkit.html; 17 18 import java.io.IOException ; 19 import java.util.Arrays ; 20 import java.util.Collections ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 import java.util.Map ; 24 import java.util.Set ; 25 26 import javax.faces.FacesException; 27 import javax.faces.component.EditableValueHolder; 28 import javax.faces.component.NamingContainer; 29 import javax.faces.component.UIComponent; 30 import javax.faces.component.UIForm; 31 import javax.faces.component.UISelectMany; 32 import javax.faces.component.UISelectOne; 33 import javax.faces.component.UIViewRoot; 34 import javax.faces.context.FacesContext; 35 import javax.faces.context.ResponseWriter; 36 import javax.faces.convert.Converter; 37 import javax.faces.model.SelectItem; 38 import javax.faces.model.SelectItemGroup; 39 40 import org.apache.commons.logging.Log; 41 import org.apache.commons.logging.LogFactory; 42 import org.apache.myfaces.config.MyfacesConfig; 43 import org.apache.myfaces.renderkit.RendererUtils; 44 import org.apache.myfaces.renderkit.html.util.DummyFormUtils; 45 import org.apache.myfaces.renderkit.html.util.JavascriptUtils; 46 47 125 public final class HtmlRendererUtils { 126 private static final Log log = LogFactory.getLog(HtmlRendererUtils.class); 127 128 private static final String LINE_SEPARATOR = System.getProperty( 130 "line.separator", "\r\n"); 131 132 private static final String HIDDEN_COMMANDLINK_FIELD_NAME = "_link_hidden_"; 133 134 135 private HtmlRendererUtils() { 136 } 138 139 145 public static void decodeUIInput(FacesContext facesContext, 146 UIComponent component) { 147 if (!(component instanceof EditableValueHolder)) { 148 throw new IllegalArgumentException ("Component " 149 + component.getClientId(facesContext) 150 + " is not an EditableValueHolder"); 151 } 152 Map paramMap = facesContext.getExternalContext() 153 .getRequestParameterMap(); 154 String clientId = component.getClientId(facesContext); 155 if (paramMap.containsKey(clientId)) { 156 ((EditableValueHolder) component).setSubmittedValue(paramMap 158 .get(clientId)); 159 } else { 160 if(!isDisabledOrReadOnly(component)) 163 { 164 ((EditableValueHolder) component).setSubmittedValue( RendererUtils.EMPTY_STRING ); 165 } 166 } 167 } 168 169 175 public static void decodeUISelectBoolean(FacesContext facesContext, 176 UIComponent component) { 177 if (!(component instanceof EditableValueHolder)) { 178 throw new IllegalArgumentException ("Component " 179 + component.getClientId(facesContext) 180 + " is not an EditableValueHolder"); 181 } 182 Map paramMap = facesContext.getExternalContext() 183 .getRequestParameterMap(); 184 String clientId = component.getClientId(facesContext); 185 if (paramMap.containsKey(clientId)) { 186 String reqValue = (String ) paramMap.get(clientId); 187 if (reqValue != null 188 && (reqValue.equalsIgnoreCase("on") 189 || reqValue.equalsIgnoreCase("yes") || reqValue 190 .equalsIgnoreCase("true"))) { 191 ((EditableValueHolder) component) 192 .setSubmittedValue(Boolean.TRUE); 193 } else { 194 ((EditableValueHolder) component) 195 .setSubmittedValue(Boolean.FALSE); 196 } 197 } else { 198 if(!isDisabledOrReadOnly(component)) 201 { 202 ((EditableValueHolder) component).setSubmittedValue( Boolean.FALSE ); 203 } 205 } 206 } 207 208 public static boolean isDisabledOrReadOnly(UIComponent component) 209 { 210 return isTrue(component.getAttributes().get("disabled")) || 211 isTrue(component.getAttributes().get("readOnly")); 212 } 213 214 private static boolean isTrue(Object obj) 215 { 216 if(!(obj instanceof Boolean )) 217 return false; 218 219 return ((Boolean ) obj).booleanValue(); 220 } 221 222 228 public static void decodeUISelectMany(FacesContext facesContext, 229 UIComponent component) { 230 if (!(component instanceof EditableValueHolder)) { 231 throw new IllegalArgumentException ("Component " 232 + component.getClientId(facesContext) 233 + " is not an EditableValueHolder"); 234 } 235 Map paramValuesMap = facesContext.getExternalContext() 236 .getRequestParameterValuesMap(); 237 String clientId = component.getClientId(facesContext); 238 if (paramValuesMap.containsKey(clientId)) { 239 String [] reqValues = (String []) paramValuesMap.get(clientId); 240 ((EditableValueHolder) component).setSubmittedValue(reqValues); 241 } else { 242 if(!isDisabledOrReadOnly(component)) 245 { 246 ((EditableValueHolder) component).setSubmittedValue( RendererUtils.EMPTY_STRING ); 247 } 249 } 250 } 251 252 258 public static void decodeUISelectOne(FacesContext facesContext, 259 UIComponent component) { 260 if (!(component instanceof EditableValueHolder)) { 261 throw new IllegalArgumentException ("Component " 262 + component.getClientId(facesContext) 263 + " is not an EditableValueHolder"); 264 } 265 Map paramMap = facesContext.getExternalContext() 266 .getRequestParameterMap(); 267 String clientId = component.getClientId(facesContext); 268 if (paramMap.containsKey(clientId)) { 269 ((EditableValueHolder) component).setSubmittedValue(paramMap 271 .get(clientId)); 272 } else { 273 276 if(!isDisabledOrReadOnly(component)) 277 { 278 ((EditableValueHolder) component).setSubmittedValue( RendererUtils.EMPTY_STRING ); 279 } 281 } 282 } 283 284 311 312 public static void renderListbox(FacesContext facesContext, 313 UISelectOne selectOne, boolean disabled, int size) 314 throws IOException { 315 internalRenderSelect(facesContext, selectOne, disabled, size, false); 316 } 317 318 public static void renderListbox(FacesContext facesContext, 319 UISelectMany selectMany, boolean disabled, int size) 320 throws IOException { 321 internalRenderSelect(facesContext, selectMany, disabled, size, true); 322 } 323 324 public static void renderMenu(FacesContext facesContext, 325 UISelectOne selectOne, boolean disabled) throws IOException { 326 internalRenderSelect(facesContext, selectOne, disabled, 1, false); 327 } 328 329 public static void renderMenu(FacesContext facesContext, 330 UISelectMany selectMany, boolean disabled) throws IOException { 331 internalRenderSelect(facesContext, selectMany, disabled, 1, true); 332 } 333 334 private static void internalRenderSelect(FacesContext facesContext, 335 UIComponent uiComponent, boolean disabled, int size, 336 boolean selectMany) throws IOException { 337 ResponseWriter writer = facesContext.getResponseWriter(); 338 339 writer.startElement(HTML.SELECT_ELEM, uiComponent); 340 HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext); 341 writer.writeAttribute(HTML.NAME_ATTR, uiComponent 342 .getClientId(facesContext), null); 343 344 List selectItemList; 345 Converter converter; 346 if (selectMany) { 347 writer.writeAttribute(HTML.MULTIPLE_ATTR, "true", null); 348 selectItemList = RendererUtils 349 .getSelectItemList((UISelectMany) uiComponent); 350 try { 351 converter = RendererUtils.findUISelectManyConverter( 352 facesContext, (UISelectMany) uiComponent); 353 } catch (FacesException e) { 354 log.error("Error finding Converter for component with id " 355 + uiComponent.getClientId(facesContext)); 356 converter = null; 357 } 358 } else { 359 selectItemList = RendererUtils 360 .getSelectItemList((UISelectOne) uiComponent); 361 try { 362 converter = RendererUtils.findUIOutputConverter(facesContext, 363 (UISelectOne) uiComponent); 364 } catch (FacesException e) { 365 log.error("Error finding Converter for component with id " 366 + uiComponent.getClientId(facesContext)); 367 converter = null; 368 } 369 } 370 371 if (size == 0) { 372 writer.writeAttribute(HTML.SIZE_ATTR, Integer 374 .toString(selectItemList.size()), null); 375 } else { 376 writer.writeAttribute(HTML.SIZE_ATTR, Integer.toString(size), null); 377 } 378 renderHTMLAttributes(writer, uiComponent, 379 HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED); 380 if (disabled) { 381 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null); 382 } 383 384 Set lookupSet; 385 boolean useSubmittedValue; 386 if (selectMany) { 387 UISelectMany uiSelectMany = (UISelectMany) uiComponent; 388 lookupSet = RendererUtils.getSubmittedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany); 389 if (lookupSet == null) 390 { 391 useSubmittedValue = false; 392 lookupSet = RendererUtils.getSelectedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany); 393 } 394 else 395 { 396 useSubmittedValue = true; 397 } 398 } else { 399 UISelectOne uiSelectOne = (UISelectOne) uiComponent; 400 Object lookup = uiSelectOne.getSubmittedValue(); 401 if (lookup == null) 402 { 403 useSubmittedValue = false; 404 lookup = uiSelectOne.getValue(); 405 } 406 else 407 { 408 useSubmittedValue = true; 409 } 410 String lookupString = RendererUtils.getConvertedStringValue(facesContext, uiComponent, converter, lookup); 411 lookupSet = Collections.singleton(lookupString); 412 } 413 414 renderSelectOptions(facesContext, uiComponent, converter, lookupSet, 415 useSubmittedValue, selectItemList); 416 writer.writeText("", null); 418 writer.endElement(HTML.SELECT_ELEM); 419 } 420 421 441 private static void renderSelectOptions(FacesContext context, 442 UIComponent component, Converter converter, Set lookupSet, 443 boolean useSubmittedValue, List selectItemList) throws IOException { 444 ResponseWriter writer = context.getResponseWriter(); 445 446 for (Iterator it = selectItemList.iterator(); it.hasNext();) { 447 SelectItem selectItem = (SelectItem) it.next(); 448 449 if (selectItem instanceof SelectItemGroup) { 450 writer.startElement(HTML.OPTGROUP_ELEM, null); 451 writer.writeAttribute(HTML.LABEL_ATTR, selectItem.getLabel(), 452 null); 453 SelectItem[] selectItems = ((SelectItemGroup) selectItem) 454 .getSelectItems(); 455 renderSelectOptions(context, component, converter, lookupSet, 456 useSubmittedValue, Arrays.asList(selectItems)); 457 writer.endElement(HTML.OPTGROUP_ELEM); 458 } else { 459 String itemStrValue = RendererUtils.getConvertedStringValue(context, component, 460 converter, selectItem); 461 462 writer.write("\t\t"); 463 writer.startElement(HTML.OPTION_ELEM, null); 464 if (itemStrValue != null) { 465 writer.writeAttribute(HTML.VALUE_ATTR, itemStrValue, null); 466 } 467 468 if (lookupSet.contains(itemStrValue)) { writer.writeAttribute(HTML.SELECTED_ATTR, 470 HTML.SELECTED_ATTR, null); 471 } 472 473 if (selectItem.isDisabled()) { 474 writer.writeAttribute(HTML.DISABLED_ATTR, 475 HTML.DISABLED_ATTR, null); 476 } 477 478 writer.writeText(selectItem.getLabel(), null); 479 480 writer.endElement(HTML.OPTION_ELEM); 481 } 482 } 483 } 484 485 512 513 public static void writePrettyLineSeparator(FacesContext facesContext) 514 throws IOException { 515 if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()) 516 .isPrettyHtml()) { 517 facesContext.getResponseWriter().write(LINE_SEPARATOR); 518 } 519 } 520 521 public static void writePrettyIndent(FacesContext facesContext) 522 throws IOException { 523 if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()) 524 .isPrettyHtml()) { 525 facesContext.getResponseWriter().write('\t'); 526 } 527 } 528 529 533 public static boolean renderHTMLAttribute(ResponseWriter writer, 534 String componentProperty, String attrName, Object value) 535 throws IOException { 536 if (!RendererUtils.isDefaultAttributeValue(value)) { 537 String htmlAttrName = attrName.equals(HTML.STYLE_CLASS_ATTR) ? HTML.CLASS_ATTR 539 : attrName; 540 writer.writeAttribute(htmlAttrName, value, componentProperty); 541 return true; 542 } 543 544 return false; 545 } 546 547 551 public static boolean renderHTMLAttribute(ResponseWriter writer, 552 UIComponent component, String componentProperty, String htmlAttrName) 553 throws IOException { 554 Object value = component.getAttributes().get(componentProperty); 555 return renderHTMLAttribute(writer, componentProperty, htmlAttrName, 556 value); 557 } 558 559 563 public static boolean renderHTMLAttributes(ResponseWriter writer, 564 UIComponent component, String [] attributes) throws IOException { 565 boolean somethingDone = false; 566 for (int i = 0, len = attributes.length; i < len; i++) { 567 String attrName = attributes[i]; 568 if (renderHTMLAttribute(writer, component, attrName, attrName)) { 569 somethingDone = true; 570 } 571 } 572 return somethingDone; 573 } 574 575 public static boolean renderHTMLAttributeWithOptionalStartElement( 576 ResponseWriter writer, UIComponent component, String elementName, 577 String attrName, Object value, boolean startElementWritten) 578 throws IOException { 579 if (!RendererUtils.isDefaultAttributeValue(value)) { 580 if (!startElementWritten) { 581 writer.startElement(elementName, component); 582 startElementWritten = true; 583 } 584 renderHTMLAttribute(writer, attrName, attrName, value); 585 } 586 return startElementWritten; 587 } 588 589 public static boolean renderHTMLAttributesWithOptionalStartElement( 590 ResponseWriter writer, UIComponent component, String elementName, 591 String [] attributes) throws IOException { 592 boolean startElementWritten = false; 593 for (int i = 0, len = attributes.length; i < len; i++) { 594 String attrName = attributes[i]; 595 Object value = component.getAttributes().get(attrName); 596 if (!RendererUtils.isDefaultAttributeValue(value)) { 597 if (!startElementWritten) { 598 writer.startElement(elementName, component); 599 startElementWritten = true; 600 } 601 renderHTMLAttribute(writer, attrName, attrName, value); 602 } 603 } 604 return startElementWritten; 605 } 606 607 public static boolean renderOptionalEndElement(ResponseWriter writer, 608 UIComponent component, String elementName, String [] attributes) 609 throws IOException { 610 boolean endElementNeeded = false; 611 for (int i = 0, len = attributes.length; i < len; i++) { 612 String attrName = attributes[i]; 613 Object value = component.getAttributes().get(attrName); 614 if (!RendererUtils.isDefaultAttributeValue(value)) { 615 endElementNeeded = true; 616 break; 617 } 618 } 619 if (endElementNeeded) { 620 writer.endElement(elementName); 621 return true; 622 } 623 624 return false; 625 } 626 627 public static void writeIdIfNecessary(ResponseWriter writer, UIComponent component, 628 FacesContext facesContext) 629 throws IOException 630 { 631 if(component.getId()!=null && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) 632 { 633 writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext),null); 634 } 635 } 636 637 public static class LinkParameter { 638 private String _name; 639 640 private Object _value; 641 642 public String getName() { 643 return _name; 644 } 645 646 public void setName(String name) { 647 _name = name; 648 } 649 650 public Object getValue() { 651 return _value; 652 } 653 654 public void setValue(Object value) { 655 _value = value; 656 } 657 658 } 659 660 public static void renderHiddenCommandFormParams(ResponseWriter writer, 661 Set dummyFormParams) throws IOException { 662 for (Iterator it = dummyFormParams.iterator(); it.hasNext();) { 663 writer.startElement(HTML.INPUT_ELEM, null); 664 writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null); 665 writer.writeAttribute(HTML.NAME_ATTR, it.next(), null); 666 writer.endElement(HTML.INPUT_ELEM); 667 } 668 } 669 670 682 public static void renderClearHiddenCommandFormParamsFunction( 683 ResponseWriter writer, String formName, Set dummyFormParams, 684 String formTarget) throws IOException { 685 String functionName = getClearHiddenCommandFormParamsFunctionName(formName); 687 writer.startElement(HTML.SCRIPT_ELEM, null); 688 writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", null); 689 writer.write("\n<!--"); 690 writer.write("\nfunction "); 691 writer.write(functionName); 692 writer.write("() {"); 693 if (dummyFormParams != null) { 694 writer.write("\n var f = document.forms['"); 695 writer.write(formName); 696 writer.write("'];"); 697 for (Iterator it = dummyFormParams.iterator(); it.hasNext();) { 698 writer.write("\n f.elements['"); 699 writer.write((String ) it.next()); 700 writer.write("'].value=null;"); 701 } 702 } 703 writer.write("\n f.target="); 705 if (formTarget == null || formTarget.length() == 0) { 706 writer.write("'';"); 710 } else { 711 writer.write("'"); 712 writer.write(formTarget); 713 writer.write("';"); 714 } 715 writer.write("\n}"); 716 717 writer.write("\n"); 721 writer.write(functionName); 722 writer.write("();"); 723 724 writer.write("\n//-->\n"); 725 writer.endElement(HTML.SCRIPT_ELEM); 726 } 727 728 734 public static String getClearHiddenCommandFormParamsFunctionName( 735 String formName) { 736 return "clear_" 737 + JavascriptUtils.getValidJavascriptName(formName, false); 738 } 739 740 public static String getFormName(UIComponent component, FacesContext context) { 741 UIComponent parent = component.getParent(); 743 while (parent != null && !(parent instanceof UIForm)) { 744 parent = parent.getParent(); 745 } 746 747 if (parent != null) { 748 return ((UIForm) parent).getClientId(context); 750 } 751 return DummyFormUtils.DUMMY_FORM_NAME; 754 } 755 756 public static String getHiddenCommandLinkFieldName(String formName) { 757 return formName + NamingContainer.SEPARATOR_CHAR 758 + HIDDEN_COMMANDLINK_FIELD_NAME; 759 } 760 761 } | Popular Tags |