001 package org.apache.myfaces.tobago.component; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import org.apache.commons.logging.Log; 021 import org.apache.commons.logging.LogFactory; 022 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_COLUMNS; 023 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_DIRECT_LINK_COUNT; 024 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_FIRST; 025 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_INNER_WIDTH; 026 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LAYOUT_WIDTH; 027 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_ROWS; 028 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_SELECTABLE; 029 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_SELECTED_LIST_STRING; 030 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_SHOW_DIRECT_LINKS; 031 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_SHOW_HEADER; 032 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_SHOW_PAGE_RANGE; 033 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_SHOW_ROW_RANGE; 034 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STATE; 035 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_WIDTH_LIST_STRING; 036 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_OUT; 037 import org.apache.myfaces.tobago.ajax.api.AjaxComponent; 038 import org.apache.myfaces.tobago.ajax.api.AjaxPhaseListener; 039 import org.apache.myfaces.tobago.ajax.api.AjaxUtils; 040 import org.apache.myfaces.tobago.event.PageActionEvent; 041 import org.apache.myfaces.tobago.event.SheetStateChangeEvent; 042 import org.apache.myfaces.tobago.event.SheetStateChangeListener; 043 import org.apache.myfaces.tobago.event.SheetStateChangeSource; 044 import org.apache.myfaces.tobago.event.SortActionEvent; 045 import org.apache.myfaces.tobago.event.SortActionSource; 046 import org.apache.myfaces.tobago.model.SheetState; 047 import org.apache.myfaces.tobago.renderkit.LayoutInformationProvider; 048 import org.apache.myfaces.tobago.renderkit.LayoutableRendererBase; 049 import org.apache.myfaces.tobago.renderkit.SheetRendererWorkaround; 050 import org.apache.myfaces.tobago.util.LayoutInfo; 051 import org.apache.myfaces.tobago.util.LayoutUtil; 052 import org.apache.myfaces.tobago.util.StringUtil; 053 054 import javax.faces.component.UIColumn; 055 import javax.faces.component.UIComponent; 056 import javax.faces.context.FacesContext; 057 import javax.faces.el.EvaluationException; 058 import javax.faces.el.MethodBinding; 059 import javax.faces.el.ValueBinding; 060 import javax.faces.event.AbortProcessingException; 061 import javax.faces.event.FacesEvent; 062 import javax.faces.event.PhaseId; 063 import java.io.IOException; 064 import java.util.ArrayList; 065 import java.util.List; 066 import java.util.Map; 067 068 public class UIData extends javax.faces.component.UIData 069 implements SheetStateChangeSource, SortActionSource, AjaxComponent { 070 071 private static final Log LOG = LogFactory.getLog(UIData.class); 072 073 public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.Data"; 074 075 public static final String FACET_SORTER = "sorter"; 076 public static final String SORTER_ID = "sorter"; 077 public static final String ATTR_SCROLL_POSITION = "attrScrollPosition"; 078 079 public static final String NONE = "none"; 080 public static final String SINGLE = "single"; 081 public static final String MULTI = "multi"; 082 public static final int DEFAULT_DIRECT_LINK_COUNT = 9; 083 public static final int DEFAULT_ROW_COUNT = 100; 084 public static final String ROW_IDX_REGEX = "^\\d+" + SEPARATOR_CHAR + ".*"; 085 private static final String DEFAULT_SELECTABLE = MULTI; 086 087 private MethodBinding stateChangeListener; 088 private List<Integer> widthList; 089 private MethodBinding sortActionListener; 090 private SheetState sheetState; 091 private Boolean showHeader; 092 private String showRowRange; 093 private String showPageRange; 094 private String showDirectLinks; 095 private String columns; 096 private Integer directLinkCount; 097 private Integer rows; 098 099 private String selectable; 100 101 public void encodeBegin(FacesContext facesContext) throws IOException { 102 UILayout.prepareDimension(facesContext, this); 103 SheetState state = getSheetState(facesContext); 104 if (state.getFirst() > -1 && state.getFirst() < getRowCount()) { 105 ValueBinding valueBinding = getValueBinding(ATTR_FIRST); 106 if (valueBinding != null) { 107 valueBinding.setValue(facesContext, state.getFirst()); 108 } else { 109 setFirst(state.getFirst()); 110 } 111 } 112 super.encodeBegin(facesContext); 113 } 114 115 public void encodeEnd(FacesContext facesContext) throws IOException { 116 setupState(facesContext); 117 prepareDimensions(facesContext); 118 super.encodeEnd(facesContext); 119 } 120 121 public String getShowRowRange() { 122 if (showRowRange != null) { 123 return showRowRange; 124 } 125 ValueBinding vb = getValueBinding(ATTR_SHOW_ROW_RANGE); 126 if (vb != null) { 127 return (String) vb.getValue(getFacesContext()); 128 } else { 129 return NONE; 130 } 131 } 132 133 public void setShowRowRange(String showRowRange) { 134 this.showRowRange = showRowRange; 135 } 136 137 public String getShowPageRange() { 138 if (showPageRange != null) { 139 return showPageRange; 140 } 141 ValueBinding vb = getValueBinding(ATTR_SHOW_PAGE_RANGE); 142 if (vb != null) { 143 return (String) vb.getValue(getFacesContext()); 144 } else { 145 return NONE; 146 } 147 } 148 149 public void setShowPageRange(String showPageRange) { 150 this.showPageRange = showPageRange; 151 } 152 153 public String getColumns() { 154 if (columns != null) { 155 return columns; 156 } 157 ValueBinding vb = getValueBinding(ATTR_COLUMNS); 158 if (vb != null) { 159 return (String) vb.getValue(getFacesContext()); 160 } else { 161 return null; 162 } 163 } 164 165 public void setColumns(String columns) { 166 this.columns = columns; 167 } 168 169 public String getShowDirectLinks() { 170 if (showDirectLinks != null) { 171 return showDirectLinks; 172 } 173 ValueBinding vb = getValueBinding(ATTR_SHOW_DIRECT_LINKS); 174 if (vb != null) { 175 return (String) vb.getValue(getFacesContext()); 176 } else { 177 return NONE; 178 } 179 } 180 181 public void setShowDirectLinks(String showDirectLinks) { 182 this.showDirectLinks = showDirectLinks; 183 } 184 185 public String getSelectable() { 186 if (selectable != null) { 187 return selectable; 188 } 189 ValueBinding vb = getValueBinding(ATTR_SELECTABLE); 190 if (vb != null) { 191 return (String) vb.getValue(getFacesContext()); 192 } else { 193 return DEFAULT_SELECTABLE; 194 } 195 } 196 197 public void setSelectable(String selectable) { 198 this.selectable = selectable; 199 } 200 201 public Integer getDirectLinkCount() { 202 if (directLinkCount != null) { 203 return directLinkCount; 204 } 205 ValueBinding vb = getValueBinding(ATTR_DIRECT_LINK_COUNT); 206 if (vb != null) { 207 return (Integer) vb.getValue(getFacesContext()); 208 } else { 209 return DEFAULT_DIRECT_LINK_COUNT; 210 } 211 } 212 213 public void setDirectLinkCount(Integer directLinkCount) { 214 this.directLinkCount = directLinkCount; 215 } 216 217 private void setupState(FacesContext facesContext) { 218 SheetState state = getSheetState(facesContext); 219 ensureColumnWidthList(facesContext, state); 220 } 221 222 public void setState(SheetState state) { 223 this.sheetState = state; 224 } 225 226 public SheetState getSheetState(FacesContext facesContext) { 227 if (sheetState != null) { 228 return sheetState; 229 } else { 230 ValueBinding stateBinding = getValueBinding(ATTR_STATE); 231 if (stateBinding != null) { 232 SheetState state = (SheetState) stateBinding.getValue(facesContext); 233 if (state == null) { 234 state = new SheetState(); 235 stateBinding.setValue(facesContext, state); 236 } 237 return state; 238 } else { 239 sheetState = new SheetState(); 240 return sheetState; 241 } 242 } 243 } 244 245 private void ensureColumnWidthList(FacesContext facesContext, SheetState state) { 246 List<Integer> currentWidthList = null; 247 List<UIColumn> columns = getRendererdColumns(); 248 249 final Map attributes = getAttributes(); 250 String widthListString = null; 251 252 if (state != null) { 253 widthListString = state.getColumnWidths(); 254 } 255 if (widthListString == null) { 256 widthListString = 257 (String) attributes.get(ATTR_WIDTH_LIST_STRING); 258 } 259 260 if (widthListString != null) { 261 currentWidthList = StringUtil.parseIntegerList(widthListString); 262 } 263 if (currentWidthList != null && currentWidthList.size() != columns.size()) { 264 currentWidthList = null; 265 } 266 267 268 if (currentWidthList == null) { 269 String columnLayout = 270 (String) attributes.get(ATTR_COLUMNS); 271 List<UIColumn> allColumns = getAllColumns(); 272 273 if (columnLayout == null && allColumns.size() > 0) { 274 StringBuilder sb = new StringBuilder(); 275 for (UIColumn allColumn : allColumns) { 276 sb.append("1*;"); 277 } 278 columnLayout = sb.deleteCharAt(sb.lastIndexOf(";")).toString(); 279 if (LOG.isWarnEnabled()) { 280 LOG.warn( 281 "No columns found! Using created layout tokens: " + columnLayout); 282 } 283 } 284 String[] layoutTokens 285 = LayoutInfo.createLayoutTokens(columnLayout, allColumns.size(), "1*"); 286 if (layoutTokens.length != allColumns.size()) { 287 LOG.warn("Count of columnLayout tokens in '" + columnLayout 288 + "' != count of columns (" + allColumns.size() + ")! " 289 + "Using default token '1*' for all columns"); 290 layoutTokens 291 = LayoutInfo.createLayoutTokens(null, allColumns.size(), "1*"); 292 } 293 294 // here we have layoutTokens for all columns 295 // now remove tokens for unrendered columns 296 boolean changed = false; 297 for (int i = 0; i < layoutTokens.length; i++) { 298 if (!allColumns.get(i).isRendered()) { 299 layoutTokens[i] = null; 300 changed = true; 301 } 302 } 303 if (changed) { 304 String[] allTokens = layoutTokens; 305 layoutTokens = new String[columns.size()]; 306 int j = 0; 307 for (String allToken : allTokens) { 308 if (allToken != null) { 309 layoutTokens[j] = allToken; 310 j++; 311 } 312 } 313 } 314 315 316 317 int space = LayoutUtil.getInnerSpace(facesContext, this, true); 318 SheetRendererWorkaround renderer 319 = (SheetRendererWorkaround) ComponentUtil.getRenderer(facesContext, this); 320 space -= renderer.getContentBorder(facesContext, this); 321 if (renderer.needVerticalScrollbar(facesContext, this)) { 322 space -= renderer.getScrollbarWidth(facesContext, this); 323 } 324 LayoutInfo layoutInfo = new LayoutInfo(getRendererdColumns().size(), 325 space, LayoutTokens.parse(layoutTokens), this.getClientId(facesContext), false); 326 parseFixedWidth(facesContext, layoutInfo); 327 layoutInfo.parseColumnLayout(space); 328 currentWidthList = layoutInfo.getSpaceList(); 329 } 330 331 if (currentWidthList != null) { 332 if (columns.size() != currentWidthList.size()) { 333 LOG.warn("widthList.size() = " + currentWidthList.size() 334 + " != columns.size() = " + columns.size() + " widthList : " 335 + LayoutInfo.listToTokenString(currentWidthList)); 336 } else { 337 this.widthList = currentWidthList; 338 } 339 } 340 } 341 342 private void parseFixedWidth(FacesContext facesContext, LayoutInfo layoutInfo) { 343 LayoutTokens tokens = layoutInfo.getLayoutTokens(); 344 for (int i = 0; i < tokens.getSize(); i++) { 345 LayoutToken token = tokens.get(i); 346 if (token instanceof FixedLayoutToken) { 347 int width = 0; 348 final List<UIColumn> columns = getRendererdColumns(); 349 if (!columns.isEmpty()) { 350 if (i < columns.size()) { 351 UIColumn column = columns.get(i); 352 if (column instanceof UIColumnSelector) { 353 LayoutInformationProvider renderer 354 = ComponentUtil.getRenderer(facesContext, column); 355 if (renderer == null) { 356 LOG.warn("can't find renderer for " + column.getClass().getName()); 357 renderer = ComponentUtil.getRenderer(facesContext, UIPanel.COMPONENT_FAMILY, RENDERER_TYPE_OUT); 358 } 359 width = renderer.getFixedWidth(facesContext, column); 360 361 } else { 362 for (UIComponent component : (List<UIComponent>) column.getChildren()) { 363 LayoutInformationProvider renderer 364 = ComponentUtil.getRenderer(facesContext, component); 365 width += renderer.getFixedWidth(facesContext, component); 366 } 367 } 368 layoutInfo.update(width, i); 369 } else { 370 layoutInfo.update(0, i); 371 if (LOG.isWarnEnabled()) { 372 LOG.warn("More LayoutTokens found than rows! skipping!"); 373 } 374 } 375 } 376 if (LOG.isDebugEnabled()) { 377 LOG.debug("set column " + i + " from fixed to with " + width); 378 } 379 } 380 } 381 } 382 383 384 private void prepareDimensions(FacesContext facesContext) { 385 // prepare width's in column's children components 386 387 List<Integer> columnWidths = getWidthList(); 388 int i = 0; 389 for (UIColumn column : getRendererdColumns()) { 390 if (i < columnWidths.size()) { 391 Integer width = columnWidths.get(i); 392 if (!(column instanceof UIColumnSelector)) { 393 if (column.getChildCount() == 1) { 394 UIComponent child = (UIComponent) column.getChildren().get(0); 395 int cellPaddingWidth = ((LayoutableRendererBase) getRenderer(facesContext)) 396 .getConfiguredValue(facesContext, this, "cellPaddingWidth"); 397 child.getAttributes().put( 398 ATTR_LAYOUT_WIDTH, width - cellPaddingWidth); 399 child.getAttributes().remove(ATTR_INNER_WIDTH); 400 } else { 401 LOG.warn("More or less than 1 child in column! " 402 + "Can't set width for column " + i + " to " + width); 403 } 404 } 405 } else { 406 LOG.warn("More columns than columnSizes! " 407 + "Can't set width for column " + i); 408 } 409 i++; 410 } 411 } 412 413 public int getLast() { 414 int last = getFirst() + getRows(); 415 return last < getRowCount() ? last : getRowCount(); 416 } 417 418 public int getPage() { 419 int first = getFirst() + 1; 420 int rows = getRows(); 421 if (rows == 0) { 422 // avoid division by zero 423 return 0; 424 } 425 if ((first % rows) > 0) { 426 return (first / rows) + 1; 427 } else { 428 return (first / rows); 429 } 430 } 431 432 public int getPages() { 433 int rows = getRows(); 434 if (rows == 0) { 435 return 0; 436 } 437 return getRowCount() / rows + (getRowCount() % rows == 0 ? 0 : 1); 438 } 439 440 public List<UIComponent> getRenderedChildrenOf(UIColumn column) { 441 List<UIComponent> children = new ArrayList<UIComponent>(); 442 for (Object o : column.getChildren()) { 443 UIComponent kid = (UIComponent) o; 444 if (kid.isRendered()) { 445 children.add(kid); 446 } 447 } 448 return children; 449 } 450 451 public boolean isAtBeginning() { 452 return getFirst() == 0; 453 } 454 455 public boolean hasRowCount() { 456 return getRowCount() != -1; 457 } 458 459 public boolean isAtEnd() { 460 if (!hasRowCount()) { 461 setRowIndex(getFirst()+getRows()+1); 462 return !isRowAvailable(); 463 } else { 464 return getFirst() >= getLastPageIndex(); 465 } 466 } 467 468 public int getLastPageIndex() { 469 int rows = getRows(); 470 if (rows == 0) { 471 // avoid division by zero 472 return 0; 473 } 474 int rowCount = getRowCount(); 475 int tail = rowCount % rows; 476 return rowCount - (tail != 0 ? tail : rows); 477 } 478 479 public void processUpdates(FacesContext context) { 480 super.processUpdates(context); 481 updateSheetState(context); 482 } 483 484 private void updateSheetState(FacesContext facesContext) { 485 SheetState state = getSheetState(facesContext); 486 if (state != null) { 487 // ensure sortActionListener 488 // getSortActionListener(); 489 // state.setSortedColumn(sortActionListener != null ? sortActionListener.getColumn() : -1); 490 // state.setAscending(sortActionListener != null && sortActionListener.isAscending()); 491 Map attributes = getAttributes(); 492 //noinspection unchecked 493 state.setSelectedRows((List<Integer>) attributes.get(ATTR_SELECTED_LIST_STRING)); 494 state.setColumnWidths((String) attributes.get(ATTR_WIDTH_LIST_STRING)); 495 state.setScrollPosition((Integer[]) attributes.get(ATTR_SCROLL_POSITION)); 496 attributes.remove(ATTR_SELECTED_LIST_STRING); 497 attributes.remove(ATTR_SCROLL_POSITION); 498 } 499 } 500 501 502 503 public Object saveState(FacesContext context) { 504 Object[] saveState = new Object[12]; 505 saveState[0] = super.saveState(context); 506 saveState[1] = sheetState; 507 saveState[2] = saveAttachedState(context, sortActionListener); 508 saveState[3] = saveAttachedState(context, stateChangeListener); 509 saveState[4] = showHeader; 510 saveState[5] = showRowRange; 511 saveState[6] = showPageRange; 512 saveState[7] = showDirectLinks; 513 saveState[8] = directLinkCount; 514 saveState[9] = selectable; 515 saveState[10] = columns; 516 saveState[11] = rows; 517 return saveState; 518 } 519 520 public void restoreState(FacesContext context, Object savedState) { 521 Object[] values = (Object[]) savedState; 522 super.restoreState(context, values[0]); 523 sheetState = (SheetState) values[1]; 524 sortActionListener = (MethodBinding) restoreAttachedState(context, values[2]); 525 stateChangeListener = (MethodBinding) restoreAttachedState(context, values[3]); 526 showHeader = (Boolean) values[4]; 527 showRowRange = (String) values[5]; 528 showPageRange = (String) values[6]; 529 showDirectLinks = (String) values[7]; 530 directLinkCount = (Integer) values[8]; 531 selectable = (String) values[9]; 532 columns = (String) values[10]; 533 rows = (Integer) values[11]; 534 } 535 536 537 public List<UIColumn> getAllColumns() { 538 List<UIColumn> columns = new ArrayList<UIColumn>(); 539 for (UIComponent kid : (List<UIComponent>) getChildren()) { 540 if (kid instanceof UIColumn) { 541 columns.add((UIColumn) kid); 542 } 543 } 544 return columns; 545 } 546 547 public List<UIColumn> getRendererdColumns() { 548 List<UIColumn> columns = new ArrayList<UIColumn>(); 549 for (UIComponent kid : (List<UIComponent>) getChildren()) { 550 if (kid instanceof UIColumn && kid.isRendered()) { 551 columns.add((UIColumn) kid); 552 } 553 } 554 return columns; 555 } 556 557 public MethodBinding getSortActionListener() { 558 if (sortActionListener != null) { 559 return sortActionListener; 560 } else { 561 return new Sorter(); 562 } 563 } 564 565 public void setSortActionListener(MethodBinding sortActionListener) { 566 this.sortActionListener = sortActionListener; 567 } 568 569 public void queueEvent(FacesEvent facesEvent) { 570 UIComponent parent = getParent(); 571 if (parent == null) { 572 throw new IllegalStateException( 573 "component is not a descendant of a UIViewRoot"); 574 } 575 576 if (facesEvent.getComponent() == this 577 && (facesEvent instanceof SheetStateChangeEvent 578 || facesEvent instanceof PageActionEvent)) { 579 facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION); 580 LOG.info("queueEvent = \"" + facesEvent + "\""); 581 parent.queueEvent(facesEvent); 582 } else { 583 UIComponent source = facesEvent.getComponent(); 584 UIComponent sourceParent = source.getParent(); 585 if (sourceParent.getParent() == this 586 && source.getId() != null && source.getId().endsWith(SORTER_ID)) { 587 facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION); 588 parent.queueEvent(new SortActionEvent(this, (UIColumn) sourceParent)); 589 } else { 590 super.queueEvent(facesEvent); 591 } 592 } 593 } 594 595 public void broadcast(FacesEvent facesEvent) throws AbortProcessingException { 596 super.broadcast(facesEvent); 597 if (facesEvent instanceof SheetStateChangeEvent) { 598 invokeMethodBinding(getStateChangeListener(), facesEvent); 599 } else if (facesEvent instanceof PageActionEvent) { 600 invokeMethodBinding(new Pager(), facesEvent); 601 invokeMethodBinding(getStateChangeListener(), new SheetStateChangeEvent(this)); 602 } else if (facesEvent instanceof SortActionEvent) { 603 getSheetState(getFacesContext()).updateSortState((SortActionEvent) facesEvent); 604 invokeMethodBinding(getSortActionListener(), facesEvent); 605 } 606 } 607 608 private void invokeMethodBinding(MethodBinding methodBinding, FacesEvent event) { 609 if (methodBinding != null && event != null) { 610 try { 611 Object[] objects = new Object [] {event}; 612 methodBinding.invoke(getFacesContext(), objects); 613 } catch (EvaluationException e) { 614 Throwable cause = e.getCause(); 615 if (cause instanceof AbortProcessingException) { 616 throw (AbortProcessingException) cause; 617 } else { 618 throw e; 619 } 620 } 621 } 622 } 623 624 public void addStateChangeListener(SheetStateChangeListener listener) { 625 addFacesListener(listener); 626 } 627 628 public SheetStateChangeListener[] getStateChangeListeners() { 629 return (SheetStateChangeListener[]) getFacesListeners(SheetStateChangeListener.class); 630 } 631 632 public void removeStateChangeListener(SheetStateChangeListener listener) { 633 removeFacesListener(listener); 634 } 635 636 public MethodBinding getStateChangeListener() { 637 return stateChangeListener; 638 } 639 640 public void setStateChangeListener(MethodBinding stateChangeListener) { 641 this.stateChangeListener = stateChangeListener; 642 } 643 644 public List<Integer> getWidthList() { 645 return widthList; 646 } 647 648 public int getRows() { 649 if (rows != null) { 650 return rows; 651 } 652 ValueBinding vb = getValueBinding(ATTR_ROWS); 653 if (vb != null) { 654 return (Integer) vb.getValue(getFacesContext()); 655 } else { 656 return DEFAULT_ROW_COUNT; 657 } 658 } 659 660 public void setRows(int rows) { 661 this.rows = rows; 662 } 663 664 public boolean isShowHeader() { 665 if (showHeader != null) { 666 return showHeader; 667 } 668 ValueBinding vb = getValueBinding(ATTR_SHOW_HEADER); 669 if (vb != null) { 670 return (!Boolean.FALSE.equals(vb.getValue(getFacesContext()))); 671 } else { 672 return true; 673 } 674 } 675 676 public void setShowHeader(boolean showHeader) { 677 this.showHeader = showHeader; 678 } 679 680 public void encodeAjax(FacesContext facesContext) throws IOException { 681 setupState(facesContext); 682 prepareDimensions(facesContext); 683 // TODO neets more testing!!! 684 //if (!facesContext.getRenderResponse() && !ComponentUtil.hasErrorMessages(facesContext)) { 685 // in encodeBegin of superclass is some logic which clears the DataModel 686 // this must here also done. 687 // in RI and myfaces this could done via setValue(null) 688 ValueBinding binding = getValueBinding("value"); 689 if (binding != null) { 690 setValue(null); 691 } else { 692 setValue(getValue()); 693 } 694 //} 695 AjaxUtils.encodeAjaxComponent(facesContext, this); 696 } 697 698 public void processAjax(FacesContext facesContext) throws IOException { 699 final String ajaxId = (String) facesContext.getExternalContext() 700 .getRequestParameterMap().get(AjaxPhaseListener.AJAX_COMPONENT_ID); 701 if (ajaxId.equals(getClientId(facesContext))) { 702 AjaxUtils.processActiveAjaxComponent(facesContext, this); 703 } else { 704 AjaxUtils.processAjaxOnChildren(facesContext, this); 705 } 706 } 707 708 public Integer[] getScrollPosition() { 709 Integer[] scrollPosition = (Integer[]) getAttributes().get(ATTR_SCROLL_POSITION); 710 if (scrollPosition == null) { 711 scrollPosition = getSheetState(FacesContext.getCurrentInstance()).getScrollPosition(); 712 } 713 return scrollPosition; 714 } 715 716 717 public UIComponent findComponent(String searchId) { 718 if (searchId.matches(ROW_IDX_REGEX)) { 719 searchId = searchId.substring(searchId.indexOf(SEPARATOR_CHAR) + 1); 720 } 721 return super.findComponent(searchId); 722 } 723 }