Package org.richfaces.component

Source Code of org.richfaces.component.UIExtendedDataTable

/**
* License Agreement.
*
* JBoss RichFaces - Ajax4jsf Component Library
*
* Copyright (C) 2008 CompuGROUP Holding AG
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

*/

package org.richfaces.component;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;
import javax.faces.model.DataModel;

import org.ajax4jsf.context.AjaxContext;
import org.ajax4jsf.context.ContextInitParameters;
import org.ajax4jsf.event.AjaxEvent;
import org.ajax4jsf.model.ExtendedDataModel;
import org.apache.commons.collections.iterators.IteratorChain;
import org.richfaces.event.extdt.ChangeColumnVisibilityEvent;
import org.richfaces.event.extdt.ColumnResizeEvent;
import org.richfaces.event.extdt.DragDropEvent;
import org.richfaces.event.extdt.ExtTableFilterEvent;
import org.richfaces.event.extdt.ExtTableSortEvent;
import org.richfaces.model.ExtendedTableDataModel;
import org.richfaces.model.ExtendedTableDataModifiableModel;
import org.richfaces.model.FilterField;
import org.richfaces.model.LocaleAware;
import org.richfaces.model.Modifiable;
import org.richfaces.model.ModifiableModel;
import org.richfaces.model.Ordering;
import org.richfaces.model.SortField2;

/**
* JSF component class
*
*/
public abstract class UIExtendedDataTable extends UIDataTable implements
    Selectable, Filterable, Sortable2 {

  /**
   * COMPONENT_TYPE
   */
  public static final String COMPONENT_TYPE = "org.richfaces.ExtendedDataTable";

  /**
   * COMPONENT_FAMILY
   */
  public static final String COMPONENT_FAMILY = "org.richfaces.ExtendedDataTable";
 
  protected ExtendedDataTableState state;

  public abstract Object getActiveRowKey();

  public abstract void setActiveRowKey(Object activeRowKey);
 
  public abstract String getGroupingColumn();
 
  public abstract void setGroupingColumn(String groupingColumn);
 
  public abstract void setTableState(String tableState);
 
  public abstract String getTableState();

  public void broadcast(FacesEvent event) throws AbortProcessingException {
    super.broadcast(event);
    if (event instanceof AjaxEvent) {
      //TODO nick - add regions from component too
      AjaxContext.getCurrentInstance().addComponentToAjaxRender(this);
    } else if (event instanceof DragDropEvent) {
      processDradDrop((DragDropEvent) event);
    } else if (event instanceof ChangeColumnVisibilityEvent) {
      processChangeColumnVisibility((ChangeColumnVisibilityEvent) event);
    } else if (event instanceof ColumnResizeEvent) {
      processColumnResize((ColumnResizeEvent) event);
    } else if (event instanceof ExtTableSortEvent) {
      processSortingChange((ExtTableSortEvent) event);
    } else if (event instanceof ExtTableFilterEvent) {
      processFilteringChange((ExtTableFilterEvent) event);
    }

  }

  public void queueEvent(FacesEvent event) {
      if(event.getSource() instanceof UIExtendedDataTable) {
        if (event instanceof AjaxEvent) {
          event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
        } else if (event instanceof DragDropEvent) {
          new AjaxEvent(this).queue();
          event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
        } else if (event instanceof ChangeColumnVisibilityEvent) {
          new AjaxEvent(this).queue();
          event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
        } else if (event instanceof ColumnResizeEvent) {
          event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
        } else if (event instanceof ExtTableSortEvent) {
          new AjaxEvent(this).queue();
          event.setPhaseId(PhaseId.INVOKE_APPLICATION);
        } else if (event instanceof ExtTableFilterEvent) {
          new AjaxEvent(this).queue();
          event.setPhaseId(PhaseId.INVOKE_APPLICATION);
        }
      }
      super.queueEvent(event);
  }

  public Iterator<UIColumn> getSortedColumns() {
    return new SortedColumnsIterator(this);
  }

  public Iterator<UIColumn> getChildColumns() {
    return new ExtendedTableColumnsIterator(this);
  }

  public void processDradDrop(DragDropEvent event) {
    String dragValue = event.getDragValue().toString();// dnd_drag_script
    String dropValue = event.getDropValue().toString();// dnd_drop_script

    getState().changeColumnsOrder(dragValue, dropValue, event.isDropBefore());
    //getFacesContext().renderResponse();
  }

  public List<UIComponent> getSortedChildren() {
    return getState().sortColumns(getFacesContext(), super.getChildren());
  }

  public void processChangeColumnVisibility(ChangeColumnVisibilityEvent event) {
    getState().toggleColumnVisibility(this, event.getColumnId());
    //getFacesContext().renderResponse();
  }

  public void processSortingChange(ExtTableSortEvent event) {
    DataModel dataModel = getDataModel();
    if (dataModel instanceof ExtendedTableDataModifiableModel<?>) {
      ((ExtendedTableDataModifiableModel<?>)dataModel).resetSort();
    }
    else{
      super.resetDataModel();
    }
    getFacesContext().renderResponse();
  }

  public void processFilteringChange(ExtTableFilterEvent event) {
    DataModel dataModel = getDataModel();
    if (dataModel instanceof ExtendedTableDataModifiableModel<?>) {
      ((ExtendedTableDataModifiableModel<?>)dataModel).resetFilter();
    }
    else{
      super.resetDataModel();
    }
    resetGroupVisibilityState();
    getFacesContext().renderResponse();
  }

  public boolean isColumnVisible(UIComponent column) {
    return getState().isColumnVisible(column.getId());
  }

  public void processColumnResize(ColumnResizeEvent event) {
    getState().changeColumnSize(this, event.getColumnWidths());
    //getFacesContext().renderResponse();
  }

  public String getColumnSize(UIComponent column) {
    return getState().getColumnSize(column);
  }

  public boolean isGroupingOn() {
    //first get it from state
    String groupingColumnId = getGroupByColumnId();
    return ((groupingColumnId!=null) && (!"".equals(groupingColumnId)) && (!ExtendedDataTableState.NONE_COLUMN_ID.equals(groupingColumnId)));
  }

  /**
   * Get id of column which the data is grouped by. First tries to get it
   * from the table state. If the table state doesn't provide such
   * information, get from component attribute.
   *
   * @return id of column which the data is grouped by
   */
  public String getGroupByColumnId() {
    String id = getState().getGroupingColumnId();
    if (id == null){//grouping is not saved in state
      //get column id from attribute
      id = getGroupingColumn();
    }
    return id;
  }

  /**
   * Get column component which the data is grouped by. First tries to get it
   * from the table state. If the table state doesn't provide such
   * information, get from component attribute.
   *
   * @return column which the data is grouped by
   */
  public UIColumn getGroupByColumn() {
    if (!isGroupingOn()){
      return null;
    }
    String groupingColumnId = getGroupByColumnId();
    for (Iterator<UIColumn> columns = getChildColumns(); columns.hasNext();) {
      UIColumn child = columns.next();
      if (groupingColumnId.equalsIgnoreCase(child.getId())) {
        return child;
      }
    }
    return null;
  }

  public void setGroupByColumn(org.richfaces.component.UIColumn column) {
    if (column == null) {
      getState().disableGrouping();
    } else {
      getState().groupBy(column.getId(), column.getSortOrder());
    }
  }

  protected void resetGroupVisibilityState() {
    getState().resetGroupVisibilityState();
  }

  public void disableGrouping() {
    getState().disableGrouping();
  }

  public boolean groupIsExpanded(int index) {
    return getState().groupIsExpanded(index);
  }

  public void toggleGroup(int index) {
    getState().toggleGroup(index);
  }
 
  protected Collection<Object> getGroupPriority(){
    Collection<Object> priority = getSortPriority();
    if (isGroupingOn()) {// grouping is on
      UIColumn column = getGroupByColumn();
      if ((column.getSortOrder() == null) || (column.getSortOrder().equals(Ordering.UNSORTED))){
        column.setSortOrder(Ordering.ASCENDING);
      }
      String groupColId = column.getId();
      // try to add group column id as first
      if (priority.contains(groupColId)) {
        priority.remove(groupColId);
      }
      if (priority instanceof List) {
        ((List<Object>) priority).add(0, groupColId);
      } else {
        priority.add(groupColId);
      }
    }
    return priority;
  }

//  public Object saveState(FacesContext context) {
//    Object values[] = new Object[2];
//    values[0] = super.saveState(context);
//    values[1] = state;
//    return values;
//  }
//
//  public void restoreState(FacesContext context, Object state) {
//    Object values[] = (Object[]) state;
//    super.restoreState(context, values[0]);
//    this.state = (ExtendedDataTableState) values[1];
//  }

  public int getVisibleColumnsCount() {
    int count = 0;
    for (Iterator<UIColumn> iter = getChildColumns(); iter.hasNext();) {
      UIColumn column = iter.next();
      if (column.isRendered())
        count++;
    }// for
    return count;
  }// getVisibleColumnnCount

  @Override
  @SuppressWarnings("unchecked")
  protected ExtendedDataModel createDataModel() {
    List<FilterField> filterFields = new LinkedList<FilterField>();
    Map<String, SortField2> sortFieldsMap = new LinkedHashMap<String, SortField2>();
    Collection<Object> sortPriority = getGroupPriority();
    List<UIComponent> list = getChildren();
    for (Iterator<UIComponent> iterator = list.iterator(); iterator
        .hasNext();) {
      UIComponent component = iterator.next();
      if (component instanceof UIColumn) {
        UIColumn column = (UIColumn) component;
        FilterField filterField = column.getFilterField();
        if (filterField != null) {
          filterFields.add(filterField);
        }
        SortField2 sortField = column.getSortField();
        if (sortField != null) {
          sortFieldsMap.put(component.getId(), sortField);
        }
      }

    }
    List<SortField2> sortFields = new LinkedList<SortField2>();
   
    if (sortPriority != null) {
      for (Object object : sortPriority) {
        if (object instanceof String) {
          String id = (String) object;
          SortField2 sortField = sortFieldsMap.get(id);
          if (sortField != null) {
            sortFields.add(sortField);
            sortFieldsMap.remove(id);
          }
        }
      }
    }
    sortFields.addAll(sortFieldsMap.values());
    setFilterFields(filterFields);
    setSortFields(sortFields);
   
    ExtendedDataModel dataModel = (ExtendedDataModel)getDataModel();
    if (dataModel instanceof ExtendedTableDataModifiableModel<?>) {
      ((ExtendedTableDataModifiableModel<?>) dataModel).setVar(getVar());
    }
    if ((filterFields != null && !filterFields.isEmpty())
        || (sortFields != null && !sortFields.isEmpty())) {
      Modifiable modifiable = null;
      if (dataModel instanceof Modifiable) {
        modifiable = (Modifiable) dataModel;
      } else if (dataModel instanceof ExtendedTableDataModel<?>) {
        ExtendedTableDataModel<?> tableDataModel = (ExtendedTableDataModel<?>) dataModel;
        //ExtendedTableDataModifiableModelOld<?> modifiableModel = new ExtendedTableDataModifiableModelOld(tableDataModel, getVar());
        ExtendedTableDataModifiableModel<?> modifiableModel = new ExtendedTableDataModifiableModel(tableDataModel, getVar());
        dataModel = modifiableModel;
        modifiable = modifiableModel;
      }
      else {
        ModifiableModel modifiableModel = new ModifiableModel(dataModel, getVar());
        dataModel = modifiableModel;
        modifiable = modifiableModel; 
      }
     
      if (dataModel instanceof LocaleAware) {
        FacesContext facesContext = getFacesContext();
        if (ContextInitParameters.isDatatableUsesViewLocale(facesContext)) {
          UIViewRoot viewRoot = facesContext.getViewRoot();
          ((LocaleAware) dataModel).setLocale(viewRoot.getLocale());
        }
      }
     
      modifiable.modify(filterFields, sortFields);
    }
    return dataModel;
  }

  /**
   * Original version of this method is defined in
   * {@link org.ajax4jsf.component.UIDataAdaptor} and is called before
   * RENDER_RESPONSE phase. In that version data model is reseted which causes
   * need to sort and filter every time component is rendered.
   */
  // @Override
  protected void resetDataModel() {
    // Do not reset only for ExtendedTableDataModel model
    if (!(getDataModel() instanceof ExtendedTableDataModel<?>)) {
      super.resetDataModel();
    }
  }
 
  @SuppressWarnings("unchecked")
  public Iterator<UIComponent> fixedChildren() {
    IteratorChain chain = new IteratorChain(getFacets().values().iterator());
    //RF-1248 Adding facets to both dataChildren and fixed children
    //To make both supports and header/footer work
    for (Iterator<UIComponent> i = getChildren().iterator(); i.hasNext(); ) {
      UIComponent kid = (UIComponent)i.next();
      if (kid instanceof Column || kid instanceof UIColumn) {
        chain.addIterator(kid.getFacets().values().iterator());
      }
    }
   
    return chain;
  }

  @Override
  public void beforeRenderResponse(FacesContext context) {
    super.beforeRenderResponse(context);
   
    for (Iterator<UIColumn> columns = getChildColumns(); columns
        .hasNext();) {
      UIColumn column = columns.next();
      column.setId(column.getId());
      column.setVisible(isColumnVisible(column));
    }
   
    UIColumn groupingColumn = getGroupByColumn();
    if (groupingColumn != null) {// grouping is on
      if (groupingColumn.getSortOrder().equals(Ordering.UNSORTED)) {
        groupingColumn.setSortOrder(Ordering.ASCENDING);
      }
    }
  }
 
  @Override
  public void processUpdates(FacesContext context){
    super.processUpdates(context);
    updateTableState(context);
  }
 
  /**
   * Puts own state into component state.
   */
  protected void updateTableState(FacesContext context){
    ValueExpression ve = getValueExpression("tableState");
    if ((null != ve) && (!ve.isReadOnly(context.getELContext()))) {
      ve.setValue(context.getELContext(), getState().toString());
    }
  }//publishChanges
 
  protected ExtendedDataTableState getState() {
    if (state == null){
      state = ExtendedDataTableState.getExtendedDataTableState(this);
    }
    return state;
  }

}
TOP

Related Classes of org.richfaces.component.UIExtendedDataTable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.