Registration

Dear SAP Community Member,
In order to fully benefit from what the SAP Community has to offer, please register at:
http://scn.sap.com
Thank you,
The SAP Community team.
Skip to end of metadata
Go to start of metadata

With the standard TableSorter Class we can only sort Table Columns, but many a times it is required to sort context node for some attributes, which are not binded to the Table columns.Below I have created a generic Sorter Class following the same line as TableSorter Class to sort context node. This class can be utilized to sort on any of the attribute in the node.

Create a Java Class in any of the package of your webdynpro dc.

NodeSorter Class

import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDAbstractDropDownByIndex;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDAbstractDropDownByKey;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDAbstractInputField;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDCaption;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDCheckBox;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDLink;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDProgressIndicator;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDRadioButton;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDTable;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDTableCellEditor;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDTableColumn;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDTextEdit;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.IWDTextView;
import com.sap.tc.webdynpro.progmodel.api.IWDAttributeInfo;
import com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent;
import com.sap.tc.webdynpro.progmodel.api.IWDNode;
import com.sap.tc.webdynpro.progmodel.api.IWDNodeElement;
import com.sap.tc.webdynpro.progmodel.api.IWDViewElement;
/**
 * Helper class that makes a Web Dynpro table UI element sortable (column-wise).
 */
public final class NodeSorter
{
 
 public NodeSorter(IWDNode dataNode)
  {
  Iterator attrIterator=dataNode.getNodeInfo().iterateAttributes();
  ReversableComparator reversable = null;
  Comparator comparator = null;
  while(attrIterator.hasNext())
  {
  IWDAttributeInfo attributeInfo = (IWDAttributeInfo)attrIterator.next();
  String attributeName = attributeInfo.getName();
  reversable = new ReversableComparator( new NodeElementByAttributeComparator(attributeName, comparator));
//  set up internal data structures
  comparatorForColumn.put(attributeName, reversable);
  }
  }
  public void sort(String attributeName,IWDNode dataSource, boolean isReversed)
{
ReversableComparator reversable = (ReversableComparator)
comparatorForColumn.get(attributeName);
if(isReversed)
reversable.toggleReversed();
dataSource.sortElements(reversable);
}
  /**
   * Returns the binding of the given table cell editor's property that is
   * considered "primary" or <code>null</code> if no such binding exists or no
   * such property can be determined.
   */
  private static final String bindingOfPrimaryProperty(IWDTableCellEditor editor)
  {
 return editor instanceof IWDViewElement
   ? bindingOfPrimaryProperty((IWDViewElement) editor)
   : null;
  }
  /**
   * Returns the binding of the given view element's property that is
   * considered "primary" or <code>null</code> if no such binding exists or no
   * such property can be determined.
   */
  private static final String bindingOfPrimaryProperty(IWDViewElement element)
  {
 if (element instanceof IWDAbstractDropDownByIndex)
   return ((IWDAbstractDropDownByIndex) element).bindingOfTexts();
 if (element instanceof IWDAbstractDropDownByKey)
   return ((IWDAbstractDropDownByKey) element).bindingOfSelectedKey();
 if (element instanceof IWDAbstractInputField)
   return ((IWDAbstractInputField) element).bindingOfValue();
 if (element instanceof IWDCaption)
   return ((IWDCaption) element).bindingOfText();
 if (element instanceof IWDCheckBox)
   return ((IWDCheckBox) element).bindingOfChecked();
 if (element instanceof IWDLink)
   return ((IWDLink) element).bindingOfText();
 if (element instanceof IWDProgressIndicator)
   return ((IWDProgressIndicator) element).bindingOfPercentValue();
 if (element instanceof IWDRadioButton)
   return ((IWDRadioButton) element).bindingOfSelectedKey();
 if (element instanceof IWDTextEdit)
   return ((IWDTextEdit) element).bindingOfValue();
 if (element instanceof IWDTextView)
   return ((IWDTextView) element).bindingOfText();
 return null;
  }
  /**
   * Instance of a comparator according to the ordering imposed by the
   * implementation of <code>Comparable</code>.
   */
  private static final Comparator DEFAULT = new Comparator()
  {
 /**
  * Compares the given objects according to the ordering imposed by the first
  * ones <code>compareTo(Object)</code> function. Furthermore, <code>null</code>
  * is treated to be less than any object.
  *
  * @see java.lang.Comparable#compareTo(java.lang.Object)
  * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
  */
 public int compare(Object o1, Object o2)
 {
   if (o1 == null && o2 == null)
  return 0;
   if (o1 == null)
  return -1;
   if (o2 == null)
  return +1;
 
   return ((Comparable) o1).compareTo((Comparable) o2);
 }
  };
   
  /**
   * Map of table column to comparator (<code>ReversableComparator</code>)
   * used for sorting that column (sortable columns only).
   */
  private final Map comparatorForColumn = new HashMap();

  /**
   * Generic comparator that compares node elements by a given attribute with
   * the help of a given comparator.
   */
  public final class NodeElementByAttributeComparator implements Comparator
  {
 /**
  * Creates a new comparator for the given attribute name that compares values
  * of that attribute according to the natural ordering of that attribute's
  * type (which must implement <code>java.lang.Comparable</code>).
  */
 public NodeElementByAttributeComparator(String attributeName)
 {
   this(attributeName, null, false);
 }
 
 /**
  * Creates a new comparator for the given attribute name that compares values
  * of that attribute with the help of the given comparator. If no comparator
  * is given, the natural ordering of that attribute's type is used.
  */
 public NodeElementByAttributeComparator(String attributeName, Comparator comparator)
 {
   this(attributeName, comparator, false);
 }
 
 /**
  * Creates a new comparator for the given attribute name that compares values
  * of that attribute either as objects (i.e. "in internal format") or as text
  * (i.e. "in external format") as indicated. The ordering is the natural
  * ordering of that attribute's type (which must implement
  * <code>java.lang.Comparable</code>) in case objects are compared or the
  * natural ordering of <code>java.lang.String</code> in case texts are compared.
  */
 public NodeElementByAttributeComparator(String attributeName, boolean compareAsText)
 {
   this(attributeName, null, compareAsText);
 }
 
 /**
  * Internal constructor.
  */
 private NodeElementByAttributeComparator(String attributeName,
   Comparator comparator, boolean compareAsText)
 {
   if (attributeName == null)
  throw new IllegalArgumentException("Attribute name must not be null");
   if (comparator == null)
  comparator = DEFAULT;
 
   this.attributeName = attributeName;
   this.comparator = comparator;
   this.compareAsText = compareAsText;
 }
 
 /**
  * Compares the given objects which must be instances of <code>IWDNodeElement</code>
  * according to the values of the attribute given at construction time
  * with the help of the comparator given at construction time.
  *
  * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
  * @see com.sap.tc.webdynpro.progmodel.api.IWDNodeElement
  */
 public int compare(Object o1, Object o2)
 {
   IWDNodeElement element1 = (IWDNodeElement) o1;
   IWDNodeElement element2 = (IWDNodeElement) o2;
   Object attributeValue1 = compareAsText
  ? element1.getAttributeAsText(attributeName)
  : element1.getAttributeValue(attributeName);
   Object attributeValue2 = compareAsText
  ? element2.getAttributeAsText(attributeName)
  : element2.getAttributeValue(attributeName);
     
   return comparator.compare(attributeValue1, attributeValue2);
 }
 
 /**
  * Name of the attribute used for comparisons.
  */
 private final String attributeName;
   
 /**
  * Comparator used for comparing the attribute's values.
  */
 private final Comparator comparator;
   
 /**
  * Indicates whether attribute values are compared as text (as opposed to
  * "as objects").
  */
 private final boolean compareAsText;
  }
  /**
   * Comparator that knows how to reverse another comparator's sort direction.
   */
  private final class ReversableComparator implements Comparator
  {
 /**
  * Creates a new reversable comparator for the given other comparator.
  */
 public ReversableComparator(Comparator comparator)
 {
   if (comparator == null)
  throw new IllegalArgumentException("Comparator must not be null");
 
   this.comparator = comparator;
 }
 
 /**
  * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
  */
 public int compare(Object o1, Object o2)
 {
   return reversed
  ? -comparator.compare(o1, o2)
  :  comparator.compare(o1, o2);
 }
 
 /**
  * Tells whether the other comparator's sort direction is reversed.
  */
 public boolean isReversed()
 {
   return reversed;
 }
 
 /**
  * Determines whether the other comparator's sort direction is reversed.
  */
 public void setReversed(boolean reversed)
 {
   this.reversed = reversed;
 }
   
 /**
  * Toggles the current "sort direction".
  */
 public void toggleReversed()
 {
   reversed = !reversed;
 }
 
 /**
  * The other comparator.
  */
 private final Comparator comparator;
 
 /**
  * Whether the other comparator's sort direction is reversed.
  */
 private boolean reversed;
  }
}






Using NodeSorter Class in the Code

Create an instance of the NodeSorter Class for the context node to be sorted.Call sort method on this instance whenever sorting is required.

      

NodeSorter sorter=new NodeSorter(wdContext.node<Node name>());
         sorter.sort("<attribute name>",wdContext.node<"Node name">(),
         true/false(true:if you want to reverse sorting order) );