/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.ui.common.util; import java.text.Collator; import java.text.RuleBasedCollator; import java.util.List; import org.eclipse.jface.viewers.ContentViewer; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.teiid.designer.ui.common.widget.accumulator.AccumulatorPanel; /** * * OrderableViewerSorter * * Extension to {@link ViewerSorter} in which sorting can be turned off and on. This was done to * accommodate the needs of a table in * {@link AccumulatorPanel}. * * User may call the setStringsOrder() method to set an order for the strings. If called with a * list of strings, this list is expected to include all of the strings that may be compared for * collation, in the desired order. "Sorting" two items then merely reflects their positions in * this list. See examples in {@link org.teiid.designer.ui.common.widget.accumulator.AccumulatorPanel}. * If setStringsOrder() is called with a null list, alphabetic sorting is reinstated. * * @since 8.0 */ public class OrderableViewerSorter extends ViewerSorter { //================================================== // Instance variables //================================================== //Overridden collator private OrderableCollator collator; //================================================== // Constructors //================================================== /** * Parameterless constructor. */ public OrderableViewerSorter() { super(); try { this.collator = new OrderableCollator(); } catch (Exception ex) { //cannot happen } } //=================================================== // Instance methods //=================================================== /** * Get the collator * @return the Collator */ @Override public Collator getCollator() { return this.collator; } /** * BWP 06/05/03 Have to include this method (copied from {@link ViewerSorter}) to change last * statement from collator.compare(... to getCollator().compare(. Overriding getCollator() was * causing nothing to happen because of this apparent mistake in the method. * * Returns a negative, zero, or positive number depending on whether * the first element is less than, equal to, or greater than * the second element. * <p> * The default implementation of this method is based on * comparing the elements' categories as computed by the <code>category</code> * framework method. Elements within the same category are further * subjected to a case insensitive compare of their label strings, either * as computed by the content viewer's label provider, or their * <code>toString</code> values in other cases. Subclasses may override. * </p> * * @param viewer the viewer * @param e1 the first element * @param e2 the second element * @return a negative number if the first element is less than the * second element; the value <code>0</code> if the first element is * equal to the second element; and a positive number if the first * element is greater than the second element */ @Override public int compare(Viewer viewer, Object e1, Object e2) { int cat1 = category(e1); int cat2 = category(e2); if (cat1 != cat2) return cat1 - cat2; // cat1 == cat2 String name1; String name2; if (viewer == null || !(viewer instanceof ContentViewer)) { name1 = e1.toString(); name2 = e2.toString(); } else { IBaseLabelProvider prov = ((ContentViewer) viewer).getLabelProvider(); if (prov instanceof ILabelProvider) { ILabelProvider lprov = (ILabelProvider) prov; name1 = lprov.getText(e1); name2 = lprov.getText(e2); } else { name1 = e1.toString(); name2 = e2.toString(); } } if (name1 == null) name1 = "";//$NON-NLS-1$ if (name2 == null) name2 = "";//$NON-NLS-1$ return getCollator().compare(name1, name2); } /** * Set an order of all Strings that may be collated. If non-null, comparing two strings merely * reflects their positions in this list. So for instance, if an item is to be added to the * end of a table, the list should reflect the current contents of the table with the new item * included at the end. See examples in {@link org.teiid.designer.ui.common.widget.accumulator.AccumulatorPanel}. * If null, alphabetic sorting is reinstated. * * @param order Ordered list of strings, or null to reinstate alphabetic sorting */ public void setStringsOrder(List<String> order) { this.collator.setStringsOrder(order); } }//end OrderableViewerSorter /** * * OrderableCollator * * Extension to {@link RuleBasedCollator} to override the compare() method. A java.util.List of * Strings can be supplied. If they are present, they are expected to represent all of the items * that may be compared for collation, in the desired order. If this list is not present, then * the comparison is performed by the superclass, in other words alphabetic. This was developed for * a table shown in {@link org.teiid.designer.ui.common.widget.accumulator.AccumulatorPanel}, in which * alphabetic sorting can be turned on and off, hence the sorter needs to be able to sort * alphabetically or "sort" from an ordered list. */ class OrderableCollator extends RuleBasedCollator { //==================================================== // Instance variables //==================================================== private List<String> orderedStrings = null; //==================================================== // Constructors //==================================================== public OrderableCollator() throws Exception { super(((RuleBasedCollator)Collator.getInstance()).getRules()); } //==================================================== // Instance methods //==================================================== /** * Set the ordered list to replace the alphabetic sort. If setting to null, alphabetic * sorting is turned on. * @param order Ordered list of strings to replace alphabetic sorting, or null to * instate alphabetic sorting */ public void setStringsOrder(List<String> order) { this.orderedStrings = order; } /** * Overridden compare() method. If list is present, do "comparison" based on order in list, * else have superclass do comparison. * @param source first string * @param target second string * @return <0, 0, or >0, same as superclass */ @Override public int compare(String source, String target) { int val; if (orderedStrings == null) { val = super.compare(source, target); } else { int index1 = orderedStrings.indexOf(source); int index2 = orderedStrings.indexOf(target); if ((index1 < 0) || (index2 < 0)) { val = super.compare(source, target); } else { val = index1 - index2; } } return val; } }//end OrderableCollator