Package org.apache.myfaces.trinidad.component

Source Code of org.apache.myfaces.trinidad.component.UIXTable$RowKeyFacesBeanWrapper

// WARNING: This file was automatically generated. Do not edit it directly,
//          or you will lose your changes.

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.myfaces.trinidad.component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.el.MethodExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;
import org.apache.myfaces.trinidad.bean.FacesBean;
import org.apache.myfaces.trinidad.bean.PropertyKey;
import org.apache.myfaces.trinidad.event.RangeChangeEvent;
import org.apache.myfaces.trinidad.event.RangeChangeListener;
import org.apache.myfaces.trinidad.event.RowDisclosureEvent;
import org.apache.myfaces.trinidad.event.RowDisclosureListener;
import org.apache.myfaces.trinidad.event.SelectionEvent;
import org.apache.myfaces.trinidad.event.SelectionListener;
import org.apache.myfaces.trinidad.event.SortEvent;
import org.apache.myfaces.trinidad.event.SortListener;
import org.apache.myfaces.trinidad.model.CollectionModel;
import org.apache.myfaces.trinidad.model.RowKeySet;
import org.apache.myfaces.trinidad.model.RowKeySetImpl;
import org.apache.myfaces.trinidad.model.SortCriterion;
import org.apache.myfaces.trinidad.util.ComponentUtils;

/**
*
* <h4>Events:</h4>
* <table border="1" width="100%" cellpadding="3" summary="">
* <tr bgcolor="#CCCCFF" class="TableHeadingColor">
* <th align="left">Type</th>
* <th align="left">Phases</th>
* <th align="left">Description</th>
* </tr>
* <tr class="TableRowColor">
* <td valign="top"><code>org.apache.myfaces.trinidad.event.RowDisclosureEvent</code></td>
* <td valign="top" nowrap>Apply<br>Request<br>Values<br>Invoke<br>Application</td>
* <td valign="top">The expansion event is generated for a table when the detail facet of a row is expanded or collapsed. For tree or a treeTable, the expansion
                       event is generated when tree nodes are expanded or collapsed.</td>
* </tr>
* <tr class="TableRowColor">
* <td valign="top"><code>org.apache.myfaces.trinidad.event.SelectionEvent</code></td>
* <td valign="top" nowrap>Apply<br>Request<br>Values<br>Invoke<br>Application</td>
* <td valign="top">The selection event is delivered when the table selection
                       changes.</td>
* </tr>
* <tr class="TableRowColor">
* <td valign="top"><code>org.apache.myfaces.trinidad.event.RangeChangeEvent</code></td>
* <td valign="top" nowrap>Apply<br>Request<br>Values<br>Invoke<br>Application</td>
* <td valign="top">The range change event is delivered when the user
                       navigates.</td>
* </tr>
* <tr class="TableRowColor">
* <td valign="top"><code>org.apache.myfaces.trinidad.event.SortEvent</code></td>
* <td valign="top" nowrap>Apply<br>Request<br>Values<br>Invoke<br>Application</td>
* <td valign="top">The sort event is delivered when the table column sort
                       criteria is changed.</td>
* </tr>
* <tr class="TableRowColor">
* <td valign="top"><code>org.apache.myfaces.trinidad.event.AttributeChangeEvent</code></td>
* <td valign="top" nowrap>Invoke<br>Application<br>Apply<br>Request<br>Values</td>
* <td valign="top">Event delivered to describe an attribute change.  Attribute change events are not delivered for any programmatic change to a property.  They are only delivered when a renderer changes a property without the application's specific request.  An example of an attribute change event might include the width of a column that supported client-side resizing.</td>
* </tr>
* </table>
*/
public class UIXTable extends UIXIterator
                      implements CollectionComponent
{
  static public final FacesBean.Type TYPE = new FacesBean.Type(
    UIXIterator.TYPE);
  static public final PropertyKey ROW_DISCLOSURE_LISTENER_KEY =
    TYPE.registerKey("rowDisclosureListener", MethodExpression.class);
  static public final PropertyKey DISCLOSED_ROW_KEYS_KEY =
    TYPE.registerKey("disclosedRowKeys", RowKeySet.class, null, 0, PropertyKey.Mutable.OFTEN);
  static public final PropertyKey SELECTION_LISTENER_KEY =
    TYPE.registerKey("selectionListener", MethodExpression.class);
  static public final PropertyKey SELECTED_ROW_KEYS_KEY =
    TYPE.registerKey("selectedRowKeys", RowKeySet.class, null, 0, PropertyKey.Mutable.OFTEN);
  static public final PropertyKey IMMEDIATE_KEY =
    TYPE.registerKey("immediate", Boolean.class, Boolean.FALSE);
  static public final PropertyKey SORT_LISTENER_KEY =
    TYPE.registerKey("sortListener", MethodExpression.class);
  static public final PropertyKey RANGE_CHANGE_LISTENER_KEY =
    TYPE.registerKey("rangeChangeListener", MethodExpression.class);
  static public final PropertyKey SHOW_ALL_KEY =
    TYPE.registerKey("showAll", Boolean.class, Boolean.FALSE);
  static public final String DETAIL_STAMP_FACET = "detailStamp";

  static public final String COMPONENT_FAMILY =
    "org.apache.myfaces.trinidad.Table";
  static public final String COMPONENT_TYPE =
    "org.apache.myfaces.trinidad.Table";

  /**
   * Construct an instance of the UIXTable.
   */
  public UIXTable()
  {
    super("org.apache.myfaces.trinidad.Table");
  }
 
  // These are "fake" properties that allow the table to get the disclosed row keys and the
  // selected row key without triggering the call to getCollectionModel from the
  // RowKeyFacesBeanWrapper class. See the stamp state saving code for its usage.
  static private final PropertyKey _DISCLOSED_ROW_KEYS_WITHOUT_MODEL_KEY =
    TYPE.registerKey("disclosedRowKeysWithoutModel", RowKeySet.class);
  static private final PropertyKey _SELECTED_ROW_KEYS_WITHOUT_MODEL_KEY =
    TYPE.registerKey("selectedRowKeysWithoutModel", RowKeySet.class);


  /**
   * Override to update the container client id cache before decode
   */
  @Override
  public void decode(FacesContext context)
  {
    _resetContainerClientIdCache();
    super.decode(context);
  }

  /**
   * Override to update the container client id cache before validations
   */
  @Override
  public void processValidators(FacesContext context)
  {
    _resetContainerClientIdCache();
    super.processValidators(context);
  }


  /**
   * Override to update the container client id cache before updates
   */
  @Override
  public void processUpdates(FacesContext context)
  {
    _resetContainerClientIdCache();
    super.processUpdates(context);
  }

  /**
   * Override to update the container client id cache before encode
   */
  @Override
  void __encodeBegin(FacesContext context) throws IOException
  {
    _resetContainerClientIdCache();
    super.__encodeBegin(context);
  }

  /**
   * Override to return clientd ids with no currency for items in header/footer facets
   */
  @Override
  public String getContainerClientId(FacesContext context, UIComponent child)
  {
    String id;
    if (_containerClientIdCache == null || _isStampedChild(child))
    {
      // call the UIXCollection getContainerClientId, which attaches currency string to the client id
      id = getContainerClientId(context);
    }
    else
    {
      // The target is not a stamped child, so return a client id with no currency string
      id = getClientId(context);
    }

    return id;
  }

  @Override
  public void setSortCriteria(List<SortCriterion> criteria)
  {
    _sortCriteria = criteria;
    super.setSortCriteria(criteria);
  }

  /**
   * Sets the phaseID of UI events depending on the "immediate" property.
   */
  @Override
  public void queueEvent(FacesEvent event)
  {
    TableUtils.__handleQueueEvent(this, event);
    super.queueEvent(event);
  }

  /**
   * Delivers an event to the appropriate listeners.
   * @param event
   * @throws javax.faces.event.AbortProcessingException
   */
  @Override
  public void broadcast(FacesEvent event)
    throws AbortProcessingException
  {
    // the order of processing is
    // 1. do any default action handling
    // 2. invoke any actionListener method binding
    // 3. call all the registered ActionListener instances.

    // Deliver to the default RangeChangeListener
    if (event instanceof RangeChangeEvent)
    {
      RangeChangeEvent rEvent = (RangeChangeEvent) event;
      int first = rEvent.getNewStart();
      setFirst(first);
      //pu: Implicitly record a Change for 'first' attribute
      addAttributeChange("first", Integer.valueOf(first));

      if ((first == 0) && (rEvent.getNewEnd() == getRowCount()))
      {
        setShowAll(true);
        //pu: Implicitly record a Change for 'showAll' attribute
        addAttributeChange("showAll", Boolean.TRUE);
      }
      else if (isShowAll())
      {
        setShowAll(false);
        //pu: Implicitly record a Change for 'showAll' attribute
        addAttributeChange("showAll", Boolean.FALSE);
      }
      // since the range is now different we can clear the currency cache:
      clearCurrencyStringCache();

      broadcastToMethodExpression(event, getRangeChangeListener());
    }
    else if (event instanceof RowDisclosureEvent)
    {
      RowDisclosureEvent eEvent = (RowDisclosureEvent) event;
      RowKeySet set = getDisclosedRowKeys();
      set.addAll(eEvent.getAddedSet());
      set.removeAll(eEvent.getRemovedSet());
      addAttributeChange("disclosedRowKeys", set);
      broadcastToMethodExpression(event, getRowDisclosureListener());
    }
    else if (event instanceof SortEvent)
    {
      SortEvent sEvent = (SortEvent) event;
      setSortCriteria(sEvent.getSortCriteria());
      broadcastToMethodExpression(event, getSortListener());
    }
    else if (event instanceof SelectionEvent)
    {
      //pu: Implicitly record a Change for 'selectionState' attribute
      addAttributeChange("selectedRowKeys",
                         getSelectedRowKeys());
      broadcastToMethodExpression(event, getSelectionListener());
    }

    super.broadcast(event);
  }



  @Deprecated
  public void setRangeChangeListener(MethodBinding binding)
  {
    setRangeChangeListener(adaptMethodBinding(binding));
  }

  @Deprecated
  public void setSortListener(MethodBinding binding)
  {
    setSortListener(adaptMethodBinding(binding));
  }

  @Deprecated
  public void setRowDisclosureListener(MethodBinding binding)
  {
    setRowDisclosureListener(adaptMethodBinding(binding));
  }

  @Deprecated
  public void setSelectionListener(MethodBinding binding)
  {
    setSelectionListener(adaptMethodBinding(binding));
  }

  @Override
  @SuppressWarnings("unchecked")
  public Object saveState(FacesContext context)
  {
    Object o = super.saveState(context);
    if ((o == null) &&
        ((_sortCriteria == null) || _sortCriteria.isEmpty()))
      return null;

    return new Object[]{o, _sortCriteria};
  }

  @Override
  @SuppressWarnings("unchecked")
  public void restoreState(FacesContext context, Object state)
  {
    Object[] array = (Object[]) state;
    super.restoreState(context, array[0]);


    // Get the sort criteria - but *don't* call setSortCriteria()
    // here;  doing so would require getting the collection model,
    // and that may invoke client code that isn't quite in a state
    // to be invoked, in part because component "binding"s have not been
    // evaluated yet.
    List<SortCriterion> criteria = (List<SortCriterion>) array[1];
    _sortCriteria = criteria;
  }


  /**
   * Gets the data for the first selected row.
   * This is useful when using EL to get at column data for the selected
   * row when using a table with single selection.
   * @return null if there is nothing selected in the table.
   */
  public Object getSelectedRowData()
  {
    RowKeySet state = getSelectedRowKeys();
    Iterator<Object> keys = state.iterator();
    if (keys.hasNext())
    {
      Object key = keys.next();
      CollectionModel model = getCollectionModel();
      Object old = model.getRowKey();
      try
      {
        model.setRowKey(key);
        if (isRowAvailable())
          return model.getRowData();
      }
      finally
      {
        model.setRowKey(old);
      }
    }
    return null;
  }

  @Override
  protected void processFacetsAndChildren(
    FacesContext context,
    PhaseId phaseId)
  {
    // process all the facets of this table just once
    // (except for the "detailStamp" facet which must be processed once
    // per row):
    TableUtils.processFacets(context, this, this, phaseId,
      UIXTable.DETAIL_STAMP_FACET);

    // process all the facets of this table's column children:
    TableUtils.processColumnFacets(context, this, this, phaseId);

    // process all the children and the detailStamp as many times as necessary
    processStamps(context, phaseId);
  }

  /**
   * Gets the stamps. This returns the children of this component plus
   * the detail stamp (if any).
   */
  // TODO cache the result
  @Override
  protected final List<UIComponent> getStamps()
  {
    List<UIComponent> children = super.getStamps();
    UIComponent detail = getDetailStamp();
    if (detail != null)
    {
      List<UIComponent> stamps = new ArrayList<UIComponent>(children.size() + 1);
      stamps.addAll(children);
      stamps.add(detail);
      return stamps;
    }
    return children;
  }

  /**
   * Saves the state for the given stamp.
   * This method avoids changing the state of facets on columns.
   */
  @Override
  protected final Object saveStampState(FacesContext context, UIComponent stamp)
  {
    if (stamp instanceof UIXColumn)
    {
      // if it is a column, we don't want the facets processed.
      // Only the children:
      return StampState.saveChildStampState(context, stamp, this);
    }
    else
    {
      Object stampState = super.saveStampState(context, stamp);
     
      // Support for column stamping. Before this fix, nested UIXCollection can never be processed without setting
      // currency on the outer iterator. The inner collection's stamp state is only created if it is null. The inner
      // collection depends on the outer collection to save and restore the nested stamp state to null as it moves it
      // currency  during saveStampState and restoreStampState.
     
      // Now if the columns are stamped using an iterator, there could be state associated with the column headers,
      // footers etc and this is when the currency is null. So it is possible to process/iterate the af:iterator when
      // the currency on the outer table is null. This could be for layout of columns etc.
     
      // The following fix uses the internal _movingToNonNullCurrency variable to know that we are ready to start
      // iterating the stamps. If so, it saves off the state associated with  the null currency in a temporary map that
      // is restored when we are done processing our stamps (also see restoreStampState).
      if(stamp instanceof UIXIterator && _movingToNonNullCurrency)
      {
        // JIT create our temporary map
        if(_iteratorStampMap == null)
        {
          _iteratorStampMap = new HashMap<String, Object>();
        }
       
        // save off the state associated with the null currency
        _iteratorStampMap.put(stamp.getClientId(context), stampState);
       
        // reset the state of the iterator to the prestine state for null currency
        ((UIXIterator)stamp).__resetMyStampState();
       
        // now save the pristine state to the null currency so that when fresh stamp states can be created if necessary
        stampState = super.saveStampState(context, stamp);
      }
     
      return stampState;
    }
  }

  /**
   * Restores the state for the given stamp.
   * This method avoids changing the state of facets on columns.
   */
  @Override
  protected final void restoreStampState(FacesContext context, UIComponent stamp, Object stampState)
  {
    if (stamp instanceof UIXColumn)
    {
      // if it is a column, we don't want the facets processed.
      // Only the children:
      StampState.restoreChildStampState(context, stamp, this, stampState);
    }
    else
    {
      // If we are done processing our stamps and are moving back to null currency, restore the stamp state to the
      // one saved off before processing our stamps
      if(stamp instanceof UIXIterator && _movingBackToNullCurrency && _iteratorStampMap != null)
      {
        // clear the cached client id of the iterator so that we can get the one without currency
        stamp.setId(stamp.getId());
        stampState = _iteratorStampMap.get(stamp.getClientId(context));       
      }
      super.restoreStampState(context, stamp, stampState);
    }
  }

  @Override
  protected final CollectionModel createCollectionModel(
    CollectionModel current,
    Object value)
  {
    return super.createCollectionModel(current, value);
  }

  @Override
  protected void postCreateCollectionModel(CollectionModel model)
  {
    RowKeySet selectedRowKeys = getSelectedRowKeys();

    if (selectedRowKeys == null)
    {
      selectedRowKeys = new RowKeySetImpl();
      setSelectedRowKeys(selectedRowKeys);
    }

    RowKeySet disclosedRowKeys = getDisclosedRowKeys();

    if (disclosedRowKeys == null)
    {
      disclosedRowKeys = new RowKeySetImpl();
      setDisclosedRowKeys(disclosedRowKeys);
    }

    selectedRowKeys.setCollectionModel(model);
    disclosedRowKeys.setCollectionModel(model);

    // If we were perviously sorted, restore the sort order:
    if (_sortCriteria != null)
    {
      model.setSortCriteria(_sortCriteria);
    }
  }

  /**
   * Gets the internal state of this component.
   */
  @Override
  Object __getMyStampState()
  {
    Object[] state = new Object[6];
    state[0] = _sortCriteria;
    state[1] = super.__getMyStampState();
    state[2] = Integer.valueOf(getFirst());
    state[3] = Boolean.valueOf(isShowAll());

    // Use "hidden" property keys to allow the row key sets to be retrieved without the
    // RowKeyFacesBeanWrapper trying to resolve the collection model to be set into the row key
    // set. This is needed to stop the unnecessary lookup of the collection model when it is not
    // needed during stamp state saving of the table.
    RowKeySet selectedRowKeys = (RowKeySet)getProperty(_SELECTED_ROW_KEYS_WITHOUT_MODEL_KEY);
    RowKeySet disclosedRowKeys = (RowKeySet)getProperty(_DISCLOSED_ROW_KEYS_WITHOUT_MODEL_KEY);

    state[4] = selectedRowKeys;
    state[5] = disclosedRowKeys;

    return state;
  }

  /**
   * Sets the internal state of this component.
   * @param stampState the internal state is obtained from this object.
   */
  @Override
  @SuppressWarnings("unchecked")
  void __setMyStampState(Object stampState)
  {
    Object[] state = (Object[]) stampState;
    _sortCriteria = (List<SortCriterion>) state[0];
    super.__setMyStampState(state[1]);
    setFirst(((Integer) state[2]).intValue());
    setShowAll(Boolean.TRUE == state[3]);
    setSelectedRowKeys((RowKeySet) state[4]);
    setDisclosedRowKeys((RowKeySet) state[5]);
  }

  @Override
  void __resetMyStampState()
  {
    super.__resetMyStampState();
    _sortCriteria = null;
    setFirst((Integer)FIRST_KEY.getDefault());
    setShowAll(Boolean.TRUE == SHOW_ALL_KEY.getDefault());
    setSelectedRowKeys(null);
    setDisclosedRowKeys(null);
  }
 
  protected void processStamps(
    FacesContext context,
    PhaseId phaseId)
  {
    // Process all the children
    CollectionModel tableData = getCollectionModel();
    if (tableData.getRowCount() != 0)
    {
      int startIndex = getFirst();
      int endIndex = isShowAll() ? getRowCount()-1 : TableUtils.getLast(this);

      UIComponent detail = getDetailStamp();
      RowKeySet disclosureState =
        (detail == null) ? null : getDisclosedRowKeys();

      for (int i = startIndex; i <= endIndex; i++)
      {
        setRowIndex(i);
        if (isRowAvailable())
        {
          TableUtils.processStampedChildren(context, this, phaseId);

          if ((disclosureState != null) && disclosureState.isContained())
          {
            assert getRowIndex() == i;
            processComponent(context, detail, phaseId);
          }
        }
      }

      setRowIndex(-1);
    }
  }

  /**
   * Is target a stamped child UIComponent in the table body
   */
  private boolean _isStampedChild(UIComponent target)
  {
    assert _containerClientIdCache != null;
    return !_containerClientIdCache.containsKey(target);
  }

  /**
   * Reset the cache of child components used in getContainerClientId
   */
  private void _resetContainerClientIdCache()
  {
    if(_containerClientIdCache == null)
      _containerClientIdCache = new IdentityHashMap<UIComponent, Boolean>();
    else
      _containerClientIdCache.clear();

    TableUtils.cacheHeaderFooterFacets(this, _containerClientIdCache);
    TableUtils.cacheColumnHeaderFooterFacets(this, _containerClientIdCache);
  }


  @Override
  void __init()
  {
    super.__init();
    if (getSelectedRowKeys() == null)
      setSelectedRowKeys(new RowKeySetImpl());
    if (getDisclosedRowKeys() == null)
      setDisclosedRowKeys(new RowKeySetImpl());
    // if "first" is valueBound, we can't deal with it changing
    // during the lifecycle. So stash it as a local value.
    // see bug 4537121:
    setFirst(getFirst());
  }

  @Override
  protected FacesBean createFacesBean(String rendererType)
  {
    return new RowKeyFacesBeanWrapper(super.createFacesBean(rendererType));
  }

  private class RowKeyFacesBeanWrapper
    extends FacesBeanWrapper
  {
    private boolean _retrievingDisclosedRows = false;
    private boolean _retrievingSelectedRows = false;

    RowKeyFacesBeanWrapper(FacesBean bean)
    {
      super(bean);
    }

    @Override
    public Object getProperty(PropertyKey key)
    {
      if (key == _DISCLOSED_ROW_KEYS_WITHOUT_MODEL_KEY)
      {
        // This case is only true if the table is trying to serialize the disclosed row keys to
        // the stamp state of a parent UIXCollection. This work-around prevents EL evaluation to
        // get the collection model during stamp state saving. This should be permissible as the
        // state saving code does not need the collection model to be set in the row key set in
        // order to save its state.
        return super.getProperty(DISCLOSED_ROW_KEYS_KEY);
      }
      else if (key == _SELECTED_ROW_KEYS_WITHOUT_MODEL_KEY)
      {
        // This case is only true if the table is trying to serialize the selected row keys to
        // the stamp state of a parent UIXCollection. This work-around prevents EL evaluation to
        // get the collection model during stamp state saving. This should be permissible as the
        // state saving code does not need the collection model to be set in the row key set in
        // order to save its state.
        return super.getProperty(SELECTED_ROW_KEYS_KEY);
      }

      Object value = super.getProperty(key);
      if (key == DISCLOSED_ROW_KEYS_KEY)
      {
        if (!_retrievingDisclosedRows && value instanceof RowKeySet)
        {
          // Ensure that when we are retrieving and setting the collection model, this property
          // is not asked for which would create an infinite loop
          _retrievingDisclosedRows = true;

          try
          {
            RowKeySet rowKeys = (RowKeySet) value;
            // row key sets need the most recent collection model, but there is no one common entry
            // point to set this on the set besides when code asks for the value from the bean
            __flushCachedModel()//insist that we populate with the very lastest instance of the collection model
            rowKeys.setCollectionModel(getCollectionModel());
          }
          finally
          {
            _retrievingDisclosedRows = false;
          }
        }
      }
      else if (key == SELECTED_ROW_KEYS_KEY)
      {
        if (!_retrievingSelectedRows && value instanceof RowKeySet)
        {
          // Ensure that when we are retrieving and setting the collection model, this property
          // is not asked for which would create an infinite loop
          _retrievingSelectedRows = true;

          try
          {
            RowKeySet rowKeys = (RowKeySet) value;
            // row key sets need the most recent collection model, but there is no one common entry
            // point to set this on the set besides when code asks for the value from the bean
            __flushCachedModel()//insist that we populate with the very lastest instance of the collection model
            rowKeys.setCollectionModel(getCollectionModel());
          }
          finally
          {
            _retrievingSelectedRows = false;
          }
        }
      }

      return value;
    }

    @Override
    public Object saveState(FacesContext context)
    {
      RowKeySet rowKeys = (RowKeySet)super.getProperty(DISCLOSED_ROW_KEYS_KEY);
      if (rowKeys != null)
      {
        // make sure the set does not pin the model in memory
        rowKeys.setCollectionModel(null);
      }
      rowKeys = (RowKeySet)super.getProperty(SELECTED_ROW_KEYS_KEY);
      if (rowKeys != null)
      {
        // make sure the set does not pin the model in memory
        rowKeys.setCollectionModel(null);
      }
      return super.saveState(context);
    }
  }

  @Override
  public void setRowKey(Object rowKey)
  {
    _preCurrencyChange(rowKey == null);
    try
    {
      super.setRowKey(rowKey);
    }
    finally
    {
      _postCurrencyChange();
    }
  }

  @Override
  public void setRowIndex(int rowIndex)
  {
    _preCurrencyChange(rowIndex == -1);
    try
    {
      super.setRowIndex(rowIndex);
    }
    finally
    {
      _postCurrencyChange();
    }
  }
 
  /**
   * When the currency changes keep track of the fact that we are ready to start iterating the stamps vs setting
   * currency to process headers etc. If the new curency is not null but the old one was,
   * we are ready to start processing the stamps.
   *
   * Similary keep track of the fact that we are done processing the our stamps. In this case the currency moves back to
   * null after being set previously
   */
  private void _preCurrencyChange(boolean isNewCurrencyNull)
  {
    Object currencyObj = getRowKey();   
    if(currencyObj == null && !isNewCurrencyNull)
    {
      _movingToNonNullCurrency = true;
    }
   
    if(currencyObj != null && isNewCurrencyNull)
    {
      _movingBackToNullCurrency = true;
    }
  }
 
  /**
   * Clean up variables setup during _preCurrencyChange.
   */
  private void _postCurrencyChange()
  {
    _movingToNonNullCurrency = false;
   
    if(_movingBackToNullCurrency)
    {
      _iteratorStampMap = null;
    }
    _movingBackToNullCurrency = false;
  }
 
  transient private List<SortCriterion> _sortCriteria = null;
  // cache of child components inside this table header/footer facets and column header/footer
  // facets
  transient private IdentityHashMap<UIComponent, Boolean> _containerClientIdCache = null;
 
  // transient variables used to track when are going to start processing the stamps and when we are done.
  transient private boolean _movingToNonNullCurrency = false;
  transient private boolean _movingBackToNullCurrency = false;
 
  // map used to support iterator stamping of columns
  transient private Map<String, Object> _iteratorStampMap = null;

  /**
   * the component to stamp below every row which is disclosed. Adding a
   * detail facet will automatically cause the detail column to be displayed.
   */
  final public UIComponent getDetailStamp()
  {
    return getFacet(DETAIL_STAMP_FACET);
  }

  /**
   * the component to stamp below every row which is disclosed. Adding a
   * detail facet will automatically cause the detail column to be displayed.
   */
  @SuppressWarnings("unchecked")
  final public void setDetailStamp(UIComponent detailStampFacet)
  {
    getFacets().put(DETAIL_STAMP_FACET, detailStampFacet);
  }

  /**
   * Gets a method reference to an ExpansionListener
   *
   * @return  the new rowDisclosureListener value
   */
  final public MethodExpression getRowDisclosureListener()
  {
    return (MethodExpression)getProperty(ROW_DISCLOSURE_LISTENER_KEY);
  }

  /**
   * Sets a method reference to an ExpansionListener
   *
   * @param rowDisclosureListener  the new rowDisclosureListener value
   */
  final public void setRowDisclosureListener(MethodExpression rowDisclosureListener)
  {
    setProperty(ROW_DISCLOSURE_LISTENER_KEY, (rowDisclosureListener));
  }

  /**
   * Gets the set of disclosed rows for this component.
   * Each entry in the set is a rowKey.
   *
   * @return  the new disclosedRowKeys value
   */
  final public RowKeySet getDisclosedRowKeys()
  {
    return (RowKeySet)getProperty(DISCLOSED_ROW_KEYS_KEY);
  }

  /**
   * Sets the set of disclosed rows for this component.
   * Each entry in the set is a rowKey.
   *
   * @param disclosedRowKeys  the new disclosedRowKeys value
   */
  final public void setDisclosedRowKeys(RowKeySet disclosedRowKeys)
  {
    setProperty(DISCLOSED_ROW_KEYS_KEY, (disclosedRowKeys));
  }

  /**
   * Gets a method reference to a selection listener
   *
   * @return  the new selectionListener value
   */
  final public MethodExpression getSelectionListener()
  {
    return (MethodExpression)getProperty(SELECTION_LISTENER_KEY);
  }

  /**
   * Sets a method reference to a selection listener
   *
   * @param selectionListener  the new selectionListener value
   */
  final public void setSelectionListener(MethodExpression selectionListener)
  {
    setProperty(SELECTION_LISTENER_KEY, (selectionListener));
  }

  /**
   * Gets the selection state for this component.
   *
   * @return  the new selectedRowKeys value
   */
  final public RowKeySet getSelectedRowKeys()
  {
    return (RowKeySet)getProperty(SELECTED_ROW_KEYS_KEY);
  }

  /**
   * Sets the selection state for this component.
   *
   * @param selectedRowKeys  the new selectedRowKeys value
   */
  final public void setSelectedRowKeys(RowKeySet selectedRowKeys)
  {
    setProperty(SELECTED_ROW_KEYS_KEY, (selectedRowKeys));
  }

  /**
   * Gets whether or not data validation - client-side or
   *             server-side -
   *           should take place when
   *           events are generated by this component.
   *
   *           When immediate is true, the default ActionListener
   *           provided by the JavaServer Faces implementation
   *           should be executed during Apply Request Values phase
   *           of the request processing lifecycle, rather than
   *           waiting until the Invoke Application phase.
   *
   * @return  the new immediate value
   */
  final public boolean isImmediate()
  {
    return ComponentUtils.resolveBoolean(getProperty(IMMEDIATE_KEY), false);
  }

  /**
   * Sets whether or not data validation - client-side or
   *             server-side -
   *           should take place when
   *           events are generated by this component.
   *
   *           When immediate is true, the default ActionListener
   *           provided by the JavaServer Faces implementation
   *           should be executed during Apply Request Values phase
   *           of the request processing lifecycle, rather than
   *           waiting until the Invoke Application phase.
   *
   * @param immediate  the new immediate value
   */
  final public void setImmediate(boolean immediate)
  {
    setProperty(IMMEDIATE_KEY, immediate ? Boolean.TRUE : Boolean.FALSE);
  }

  /**
   * Gets a method reference to a sort listener
   *
   * @return  the new sortListener value
   */
  final public MethodExpression getSortListener()
  {
    return (MethodExpression)getProperty(SORT_LISTENER_KEY);
  }

  /**
   * Sets a method reference to a sort listener
   *
   * @param sortListener  the new sortListener value
   */
  final public void setSortListener(MethodExpression sortListener)
  {
    setProperty(SORT_LISTENER_KEY, (sortListener));
  }

  /**
   * Gets a method reference to a rangeChange listener that
   *          will be called when a new range is selected.
   *
   * @return  the new rangeChangeListener value
   */
  final public MethodExpression getRangeChangeListener()
  {
    return (MethodExpression)getProperty(RANGE_CHANGE_LISTENER_KEY);
  }

  /**
   * Sets a method reference to a rangeChange listener that
   *          will be called when a new range is selected.
   *
   * @param rangeChangeListener  the new rangeChangeListener value
   */
  final public void setRangeChangeListener(MethodExpression rangeChangeListener)
  {
    setProperty(RANGE_CHANGE_LISTENER_KEY, (rangeChangeListener));
  }

  /**
   * Gets whether the "Show All" option is selected. The "Show All" option
   *         is available if there are less than 30 options and the row count in
   *         the data model is known.
   *
   * @return  the new showAll value
   */
  final public boolean isShowAll()
  {
    return ComponentUtils.resolveBoolean(getProperty(SHOW_ALL_KEY), false);
  }

  /**
   * Sets whether the "Show All" option is selected. The "Show All" option
   *         is available if there are less than 30 options and the row count in
   *         the data model is known.
   *
   * @param showAll  the new showAll value
   */
  final public void setShowAll(boolean showAll)
  {
    setProperty(SHOW_ALL_KEY, showAll ? Boolean.TRUE : Boolean.FALSE);
  }

  /**
   * Adds a rowDisclosure listener.
   *
   * @param listener  the rowDisclosure listener to add
   */
  final public void addRowDisclosureListener(
    RowDisclosureListener listener)
  {
    addFacesListener(listener);
  }

  /**
   * Removes a rowDisclosure listener.
   *
   * @param listener  the rowDisclosure listener to remove
   */
  final public void removeRowDisclosureListener(
    RowDisclosureListener listener)
  {
    removeFacesListener(listener);
  }

  /**
   * Returns an array of attached rowDisclosure listeners.
   *
   * @return  an array of attached rowDisclosure listeners.
   */
  final public RowDisclosureListener[] getRowDisclosureListeners()
  {
    return (RowDisclosureListener[])getFacesListeners(RowDisclosureListener.class);
  }

  /**
   * Adds a selection listener.
   *
   * @param listener  the selection listener to add
   */
  final public void addSelectionListener(
    SelectionListener listener)
  {
    addFacesListener(listener);
  }

  /**
   * Removes a selection listener.
   *
   * @param listener  the selection listener to remove
   */
  final public void removeSelectionListener(
    SelectionListener listener)
  {
    removeFacesListener(listener);
  }

  /**
   * Returns an array of attached selection listeners.
   *
   * @return  an array of attached selection listeners.
   */
  final public SelectionListener[] getSelectionListeners()
  {
    return (SelectionListener[])getFacesListeners(SelectionListener.class);
  }

  /**
   * Adds a rangeChange listener.
   *
   * @param listener  the rangeChange listener to add
   */
  final public void addRangeChangeListener(
    RangeChangeListener listener)
  {
    addFacesListener(listener);
  }

  /**
   * Removes a rangeChange listener.
   *
   * @param listener  the rangeChange listener to remove
   */
  final public void removeRangeChangeListener(
    RangeChangeListener listener)
  {
    removeFacesListener(listener);
  }

  /**
   * Returns an array of attached rangeChange listeners.
   *
   * @return  an array of attached rangeChange listeners.
   */
  final public RangeChangeListener[] getRangeChangeListeners()
  {
    return (RangeChangeListener[])getFacesListeners(RangeChangeListener.class);
  }

  /**
   * Adds a sort listener.
   *
   * @param listener  the sort listener to add
   */
  final public void addSortListener(
    SortListener listener)
  {
    addFacesListener(listener);
  }

  /**
   * Removes a sort listener.
   *
   * @param listener  the sort listener to remove
   */
  final public void removeSortListener(
    SortListener listener)
  {
    removeFacesListener(listener);
  }

  /**
   * Returns an array of attached sort listeners.
   *
   * @return  an array of attached sort listeners.
   */
  final public SortListener[] getSortListeners()
  {
    return (SortListener[])getFacesListeners(SortListener.class);
  }

  @Override
  public String getFamily()
  {
    return COMPONENT_FAMILY;
  }

  @Override
  protected FacesBean.Type getBeanType()
  {
    return TYPE;
  }

  /**
   * Construct an instance of the UIXTable.
   */
  protected UIXTable(
    String rendererType
    )
  {
    super(rendererType);
  }

  static
  {
    TYPE.lockAndRegister("org.apache.myfaces.trinidad.Table","org.apache.myfaces.trinidad.Table");
  }
}
TOP

Related Classes of org.apache.myfaces.trinidad.component.UIXTable$RowKeyFacesBeanWrapper

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.