1 16 package org.apache.myfaces.component.html.ext; 17 18 import org.apache.myfaces.component.UserRoleAware; 19 import org.apache.myfaces.component.UserRoleUtils; 20 import org.apache.myfaces.component.UIColumns; 21 import org.apache.commons.logging.Log; 22 import org.apache.commons.logging.LogFactory; 23 24 import javax.faces.component.EditableValueHolder; 25 import javax.faces.component.UIComponent; 26 import javax.faces.context.FacesContext; 27 import javax.faces.el.ValueBinding; 28 import javax.faces.event.AbortProcessingException; 29 import javax.faces.event.FacesEvent; 30 import javax.faces.model.DataModel; 31 import javax.faces.render.Renderer; 32 33 import java.io.IOException ; 34 import java.sql.ResultSet ; 35 import java.util.Iterator ; 36 import java.util.List ; 37 import java.util.Map ; 38 39 96 public class HtmlDataTable 97 extends HtmlDataTableHack 98 implements UserRoleAware 99 { 100 private static final Log log = LogFactory.getLog(HtmlDataTable.class); 101 102 private static final int PROCESS_DECODES = 1; 103 private static final int PROCESS_VALIDATORS = 2; 104 private static final int PROCESS_UPDATES = 3; 105 106 private static final boolean DEFAULT_SORTASCENDING = true; 107 private static final Class OBJECT_ARRAY_CLASS = (new Object [0]).getClass(); 108 109 private transient boolean _isDataModelRestored = false; 110 111 transient private boolean _firstTimeRendered = true; 113 114 private String _sortColumn = null; 115 private Boolean _sortAscending = null; 116 117 118 public void setValue(Object value) 119 { 120 _dataModel = null; 121 _isDataModelRestored = false; 122 super.setValue(value); 123 } 124 125 126 public void setRowIndex(int rowIndex) 127 { 128 String rowIndexVar = getRowIndexVar(); 129 String rowCountVar = getRowCountVar(); 130 String previousRowDataVar = getPreviousRowDataVar(); 131 if (rowIndexVar != null || rowCountVar != null || previousRowDataVar != null) 132 { 133 Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap(); 134 135 if (previousRowDataVar != null && rowIndex >= 0) { 137 if (isRowAvailable()) 138 { 139 requestMap.put(previousRowDataVar, getRowData()); 141 } 142 else 143 { 144 requestMap.put(previousRowDataVar, null); 146 } 147 } 148 149 super.setRowIndex(rowIndex); 150 151 if (rowIndex >= 0) 152 { 153 if (rowIndexVar != null) 155 { 156 requestMap.put(rowIndexVar, new Integer (rowIndex)); 157 } 158 159 if (rowCountVar != null) 160 { 161 requestMap.put(rowCountVar, new Integer (getRowCount())); 162 } 163 } 164 else 165 { 166 if (rowIndexVar != null) 168 { 169 requestMap.remove(rowIndexVar); 170 } 171 172 if (rowCountVar != null) 173 { 174 requestMap.remove(rowCountVar); 175 } 176 177 if (previousRowDataVar != null) 178 { 179 requestMap.remove(previousRowDataVar); 180 } 181 } 182 } 183 else 184 { 185 super.setRowIndex(rowIndex); 187 } 188 } 189 190 191 public void processRestoreState(FacesContext context, Object state) 192 { 193 super.processRestoreState(context, state); 194 } 195 196 public void processDecodes(FacesContext context) 197 { 198 if(!isRendered()) 199 { 200 return; 201 } 202 super.processDecodes(context); 203 setRowIndex(-1); 204 processColumnsFacets(context, PROCESS_DECODES); 205 processColumnsChildren(context, PROCESS_DECODES); 206 setRowIndex(-1); 207 } 208 209 213 private void processColumnsChildren(FacesContext context, int processAction) 214 { 215 int first = getFirst(); 216 int rows = getRows(); 217 int last; 218 if (rows == 0) 219 { 220 last = getRowCount(); 221 } 222 else 223 { 224 last = first + rows; 225 } 226 for (int rowIndex = first; rowIndex < last; rowIndex++) 227 { 228 setRowIndex(rowIndex); 229 if (isRowAvailable()) 230 { 231 for (Iterator it = getChildren().iterator(); it.hasNext();) 232 { 233 UIComponent child = (UIComponent) it.next(); 234 if (child instanceof UIColumns) 235 { 236 if (child.isRendered()) 237 { 238 UIColumns columns = (UIColumns) child; 239 for (int colIndex = 0, size = columns.getRowCount(); colIndex < size; colIndex++) 240 { 241 columns.setRowIndex(colIndex); 242 for (Iterator columnChildIter = child.getChildren().iterator(); columnChildIter 243 .hasNext();) 244 { 245 UIComponent columnChild = (UIComponent) columnChildIter.next(); 246 process(context, columnChild, processAction); 247 } 248 } 249 columns.setRowIndex(-1); 250 } 251 } 252 } 253 } 254 } 255 } 256 257 258 262 private void processColumnsFacets(FacesContext context, int processAction) 263 { 264 for (Iterator childIter = getChildren().iterator(); childIter.hasNext();) 265 { 266 UIComponent child = (UIComponent) childIter.next(); 267 if (child instanceof UIColumns) 268 { 269 if(child.isRendered()) 270 { 271 UIColumns columns = (UIColumns) child; 272 for (int i = 0, size = columns.getRowCount(); i < size; i++) 273 { 274 columns.setRowIndex(i); 275 for (Iterator facetsIter = child.getFacets().values().iterator(); facetsIter.hasNext();) 276 { 277 UIComponent facet = (UIComponent) facetsIter.next(); 278 process(context, facet, processAction); 279 } 280 } 281 columns.setRowIndex(-1); 282 } 283 } 284 } 285 } 286 287 private void process(FacesContext context, UIComponent component, int processAction) 288 { 289 switch (processAction) 290 { 291 case PROCESS_DECODES : 292 component.processDecodes(context); 293 break; 294 case PROCESS_VALIDATORS : 295 component.processValidators(context); 296 break; 297 case PROCESS_UPDATES : 298 component.processUpdates(context); 299 break; 300 } 301 } 302 303 public void processValidators(FacesContext context) 304 { 305 if(!isRendered()) 306 { 307 return; 308 } 309 super.processValidators(context); 310 setRowIndex(-1); 311 processColumnsFacets(context, PROCESS_VALIDATORS); 312 processColumnsChildren(context, PROCESS_VALIDATORS); 313 setRowIndex(-1); 314 } 315 316 public Object processSaveState(FacesContext context) 317 { 318 return super.processSaveState(context); 319 } 320 321 public void broadcast(FacesEvent event) throws AbortProcessingException 322 { 323 super.broadcast(event); 324 } 325 326 public void processUpdates(FacesContext context) 327 { 328 if(!isRendered()) 329 { 330 return; 331 } 332 super.processUpdates(context); 333 setRowIndex(-1); 334 processColumnsFacets(context, PROCESS_UPDATES); 335 processColumnsChildren(context, PROCESS_UPDATES); 336 setRowIndex(-1); 337 338 if (_isDataModelRestored) 339 { 340 updateModelFromPreservedDataModel(context); 341 } 342 343 if (isPreserveSort()) 344 { 345 if (_sortColumn != null) 346 { 347 ValueBinding vb = getValueBinding("sortColumn"); 348 if (vb != null) 349 { 350 vb.setValue(context, _sortColumn); 351 _sortColumn = null; 352 } 353 } 354 355 if (_sortAscending != null) 356 { 357 ValueBinding vb = getValueBinding("sortAscending"); 358 if (vb != null) 359 { 360 vb.setValue(context, _sortAscending); 361 _sortAscending = null; 362 } 363 } 364 } 365 } 366 367 368 private void updateModelFromPreservedDataModel(FacesContext context) 369 { 370 ValueBinding vb = getValueBinding("value"); 371 if (vb != null && !vb.isReadOnly(context)) 372 { 373 _SerializableDataModel dm = (_SerializableDataModel)_dataModel; 374 Class type = vb.getType(context); 375 if (DataModel.class.isAssignableFrom(type)) 376 { 377 vb.setValue(context, dm); 378 } 379 else if (List .class.isAssignableFrom(type)) 380 { 381 vb.setValue(context, (List )dm.getWrappedData()); 382 } 383 else if (OBJECT_ARRAY_CLASS.isAssignableFrom(type)) 384 { 385 List lst = (List )dm.getWrappedData(); 386 vb.setValue(context, lst.toArray(new Object [lst.size()])); 387 } 388 else if (ResultSet .class.isAssignableFrom(type)) 389 { 390 throw new UnsupportedOperationException (this.getClass().getName() + " UnsupportedOperationException"); 391 } 392 else 393 { 394 List lst = (List )dm.getWrappedData(); 396 if (lst.size() > 0) 397 { 398 vb.setValue(context, lst.get(0)); 399 } 400 else 401 { 402 vb.setValue(context, null); 403 } 404 } 405 } 406 } 407 408 409 412 private boolean isAllChildrenAndFacetsValid() 413 { 414 int first = getFirst(); 415 int rows = getRows(); 416 int last; 417 if (rows == 0) 418 { 419 last = getRowCount(); 420 } 421 else 422 { 423 last = first + rows; 424 } 425 try 426 { 427 for (int rowIndex = first; rowIndex < last; rowIndex++) 428 { 429 setRowIndex(rowIndex); 430 if (isRowAvailable()) 431 { 432 if (!isAllEditableValueHoldersValidRecursive(getFacetsAndChildren())) 433 { 434 return false; 435 } 436 } 437 } 438 } 439 finally 440 { 441 setRowIndex(-1); 442 } 443 return true; 444 } 445 446 447 private boolean isAllEditableValueHoldersValidRecursive(Iterator facetsAndChildrenIterator) 448 { 449 while (facetsAndChildrenIterator.hasNext()) 450 { 451 UIComponent c = (UIComponent)facetsAndChildrenIterator.next(); 452 if (c instanceof EditableValueHolder && 453 !((EditableValueHolder)c).isValid()) 454 { 455 return false; 456 } 457 if (!isAllEditableValueHoldersValidRecursive(c.getFacetsAndChildren())) 458 { 459 return false; 460 } 461 } 462 return true; 463 } 464 465 466 protected void refresh(FacesContext context) 467 { 468 if (log.isDebugEnabled()) log.debug("Refresh for HtmlDataTable " + getClientId(context) + " was called"); 469 470 if (_firstTimeRendered || isAllChildrenAndFacetsValid()) 471 { 472 _dataModel = null; 475 if (_dataModelMap != null) _dataModelMap.clear(); 476 _isDataModelRestored = false; 477 478 _saveDescendantStates = false; } 480 else 481 { 482 _saveDescendantStates = true; } 484 } 485 486 487 public void encodeBegin(FacesContext context) throws IOException 488 { 489 491 if (isRenderedIfEmpty() || getRowCount() > 0) 492 { 493 if (context == null) throw new NullPointerException ("context"); 494 if (!isRendered()) return; 495 Renderer renderer = getRenderer(context); 496 if (renderer != null) 497 { 498 renderer.encodeBegin(context, this); 499 } 500 } 501 } 502 503 public void encodeChildren(FacesContext context) throws IOException 504 { 505 if (isRenderedIfEmpty() || getRowCount() > 0) 506 { 507 super.encodeChildren(context); 508 } 509 } 510 511 public void encodeEnd(FacesContext context) throws IOException 512 { 513 if (isRenderedIfEmpty() || getRowCount() > 0) 514 { 515 super.encodeEnd(context); 516 } 517 } 518 519 public int getFirst() 520 { 521 if (_isDataModelRestored) 522 { 523 return ((_SerializableDataModel)_dataModel).getFirst(); 525 } 526 else 527 { 528 return super.getFirst(); 529 } 530 } 531 532 public void setFirst(int first) 533 { 534 if (_isDataModelRestored) 535 { 536 ((_SerializableDataModel)_dataModel).setFirst(first); 538 } 539 super.setFirst(first); 540 } 541 542 public int getRows() 543 { 544 if (_isDataModelRestored) 545 { 546 return ((_SerializableDataModel)_dataModel).getRows(); 548 } 549 else 550 { 551 return super.getRows(); 552 } 553 } 554 555 public void setRows(int rows) 556 { 557 if (_isDataModelRestored) 558 { 559 ((_SerializableDataModel)_dataModel).setRows(rows); 561 } 562 super.setRows(rows); 563 } 564 565 566 public Object saveState(FacesContext context) 567 { 568 boolean preserveSort = isPreserveSort(); 569 Object values[] = new Object [9]; 570 values[0] = super.saveState(context); 571 values[1] = _preserveDataModel; 572 if (isPreserveDataModel()) 573 { 574 values[2] = saveAttachedState(context, getSerializableDataModel()); 575 } 576 else 577 { 578 values[2] = null; 579 } 580 values[3] = _preserveSort; 581 values[4] = preserveSort ? getSortColumn() : _sortColumn; 582 values[5] = preserveSort ? Boolean.valueOf(isSortAscending()) : _sortAscending; 583 values[6] = _renderedIfEmpty; 584 values[7] = _rowCountVar; 585 values[8] = _rowIndexVar; 586 return ((Object ) (values)); 587 } 588 589 590 public void restoreState(FacesContext context, Object state) 591 { 592 Object values[] = (Object [])state; 593 super.restoreState(context, values[0]); 594 _preserveDataModel = (Boolean )values[1]; 595 if (isPreserveDataModel()) 596 { 597 _dataModel = (_SerializableDataModel)restoreAttachedState(context, values[2]); 598 _isDataModelRestored = true; 599 } 600 else 601 { 602 _dataModel = null; 603 _isDataModelRestored = false; 604 } 605 _preserveSort = (Boolean )values[3]; 606 _sortColumn = (String )values[4]; 607 _sortAscending = (Boolean )values[5]; 608 _renderedIfEmpty = (Boolean )values[6]; 609 _rowCountVar = (String )values[7]; 610 _rowIndexVar = (String )values[8]; 611 612 _firstTimeRendered = false; 614 } 615 616 617 public _SerializableDataModel getSerializableDataModel() 618 { 619 if (_dataModel != null) 620 { 621 if (_dataModel instanceof _SerializableDataModel) 622 { 623 return (_SerializableDataModel)_dataModel; 624 } 625 else 626 { 627 return new _SerializableDataModel(getFirst(), getRows(), _dataModel); 628 } 629 } 630 631 Object value = getValue(); 632 if (value == null) 633 { 634 return null; 635 } 636 else if (value instanceof DataModel) 637 { 638 return new _SerializableDataModel(getFirst(), getRows(), (DataModel)value); 639 } 640 else if (value instanceof List ) 641 { 642 return new _SerializableListDataModel(getFirst(), getRows(), (List )value); 643 } 644 else if (OBJECT_ARRAY_CLASS.isAssignableFrom(value.getClass())) 645 { 646 return new _SerializableArrayDataModel(getFirst(), getRows(), (Object [])value); 647 } 648 else if (value instanceof ResultSet ) 649 { 650 return new _SerializableResultSetDataModel(getFirst(), getRows(), (ResultSet )value); 651 } 652 else if (value instanceof javax.servlet.jsp.jstl.sql.Result) 653 { 654 return new _SerializableResultDataModel(getFirst(), getRows(), (javax.servlet.jsp.jstl.sql.Result)value); 655 } 656 else 657 { 658 return new _SerializableScalarDataModel(getFirst(), getRows(), (Object )value); 659 } 660 } 661 662 public boolean isRendered() 663 { 664 if (!UserRoleUtils.isVisibleOnUserRole(this)) return false; 665 return super.isRendered(); 666 } 667 668 public void setSortColumn(String sortColumn) 669 { 670 _sortColumn = sortColumn; 671 ValueBinding vb = getValueBinding("sortColumn"); 674 if (vb != null) 675 { 676 vb.setValue(getFacesContext(), _sortColumn); 677 _sortColumn = null; 678 } 679 } 680 681 public String getSortColumn() 682 { 683 if (_sortColumn != null) return _sortColumn; 684 ValueBinding vb = getValueBinding("sortColumn"); 685 return vb != null ? (String )vb.getValue(getFacesContext()) : null; 686 } 687 688 public void setSortAscending(boolean sortAscending) 689 { 690 _sortAscending = Boolean.valueOf(sortAscending); 691 ValueBinding vb = getValueBinding("sortAscending"); 694 if (vb != null) 695 { 696 vb.setValue(getFacesContext(), _sortAscending); 697 _sortAscending = null; 698 } 699 } 700 701 public boolean isSortAscending() 702 { 703 if (_sortAscending != null) return _sortAscending.booleanValue(); 704 ValueBinding vb = getValueBinding("sortAscending"); 705 Boolean v = vb != null ? (Boolean )vb.getValue(getFacesContext()) : null; 706 return v != null ? v.booleanValue() : DEFAULT_SORTASCENDING; 707 } 708 709 710 711 712 713 715 public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlDataTable"; 716 private static final boolean DEFAULT_PRESERVEDATAMODEL = false; 717 private static final boolean DEFAULT_PRESERVESORT = true; 718 private static final boolean DEFAULT_RENDEREDIFEMPTY = true; 719 720 private Boolean _preserveDataModel = null; 721 private Boolean _preserveSort = null; 722 private String _enabledOnUserRole = null; 723 private String _visibleOnUserRole = null; 724 private Boolean _renderedIfEmpty = null; 725 private String _rowIndexVar = null; 726 private String _rowCountVar = null; 727 private String _previousRowDataVar = null; 728 729 public HtmlDataTable() 730 { 731 } 732 733 734 public void setPreserveDataModel(boolean preserveDataModel) 735 { 736 _preserveDataModel = Boolean.valueOf(preserveDataModel); 737 } 738 739 public boolean isPreserveDataModel() 740 { 741 if (_preserveDataModel != null) return _preserveDataModel.booleanValue(); 742 ValueBinding vb = getValueBinding("preserveDataModel"); 743 Boolean v = vb != null ? (Boolean )vb.getValue(getFacesContext()) : null; 744 return v != null ? v.booleanValue() : DEFAULT_PRESERVEDATAMODEL; 745 } 746 747 public void setPreserveSort(boolean preserveSort) 748 { 749 _preserveSort = Boolean.valueOf(preserveSort); 750 } 751 752 public boolean isPreserveSort() 753 { 754 if (_preserveSort != null) return _preserveSort.booleanValue(); 755 ValueBinding vb = getValueBinding("preserveSort"); 756 Boolean v = vb != null ? (Boolean )vb.getValue(getFacesContext()) : null; 757 return v != null ? v.booleanValue() : DEFAULT_PRESERVESORT; 758 } 759 760 public void setEnabledOnUserRole(String enabledOnUserRole) 761 { 762 _enabledOnUserRole = enabledOnUserRole; 763 } 764 765 public String getEnabledOnUserRole() 766 { 767 if (_enabledOnUserRole != null) return _enabledOnUserRole; 768 ValueBinding vb = getValueBinding("enabledOnUserRole"); 769 return vb != null ? (String )vb.getValue(getFacesContext()) : null; 770 } 771 772 public void setVisibleOnUserRole(String visibleOnUserRole) 773 { 774 _visibleOnUserRole = visibleOnUserRole; 775 } 776 777 public String getVisibleOnUserRole() 778 { 779 if (_visibleOnUserRole != null) return _visibleOnUserRole; 780 ValueBinding vb = getValueBinding("visibleOnUserRole"); 781 return vb != null ? (String )vb.getValue(getFacesContext()) : null; 782 } 783 784 public void setRenderedIfEmpty(boolean renderedIfEmpty) 785 { 786 _renderedIfEmpty = Boolean.valueOf(renderedIfEmpty); 787 } 788 789 public boolean isRenderedIfEmpty() 790 { 791 if (_renderedIfEmpty != null) return _renderedIfEmpty.booleanValue(); 792 ValueBinding vb = getValueBinding("renderedIfEmpty"); 793 Boolean v = vb != null ? (Boolean )vb.getValue(getFacesContext()) : null; 794 return v != null ? v.booleanValue() : DEFAULT_RENDEREDIFEMPTY; 795 } 796 797 public void setRowIndexVar(String rowIndexVar) 798 { 799 _rowIndexVar = rowIndexVar; 800 } 801 802 public String getRowIndexVar() 803 { 804 if (_rowIndexVar != null) return _rowIndexVar; 805 ValueBinding vb = getValueBinding("rowIndexVar"); 806 return vb != null ? (String )vb.getValue(getFacesContext()) : null; 807 } 808 809 public void setRowCountVar(String rowCountVar) 810 { 811 _rowCountVar = rowCountVar; 812 } 813 814 public String getRowCountVar() 815 { 816 if (_rowCountVar != null) return _rowCountVar; 817 ValueBinding vb = getValueBinding("rowCountVar"); 818 return vb != null ? (String )vb.getValue(getFacesContext()) : null; 819 } 820 821 public void setPreviousRowDataVar(String previousRowDataVar) 822 { 823 _previousRowDataVar = previousRowDataVar; 824 } 825 826 public String getPreviousRowDataVar() 827 { 828 if (_previousRowDataVar != null) return _previousRowDataVar; 829 ValueBinding vb = getValueBinding("previousRowDataVar"); 830 return vb != null ? (String )vb.getValue(getFacesContext()) : null; 831 } 832 833 834 835 } 837 | Popular Tags |