/* * 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.directory.studio.ldapbrowser.common.widgets.entryeditor; import java.util.Arrays; import java.util.Comparator; import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator; import org.apache.directory.studio.ldapbrowser.common.BrowserCommonConstants; import org.apache.directory.studio.ldapbrowser.core.BrowserCoreConstants; import org.apache.directory.studio.ldapbrowser.core.model.IAttribute; import org.apache.directory.studio.ldapbrowser.core.model.IValue; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; /** * The EntryEditorWidgetSorter implements the Sorter for the entry editor widget. * * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> */ public class EntryEditorWidgetSorter extends ViewerSorter implements SelectionListener { /** The tree viewer. */ private TreeViewer viewer; /** The sort property. */ private int sortBy; /** The sort order. */ private int sortOrder; /** The preferences. */ private EntryEditorWidgetPreferences preferences; /** * Creates a new instance of EntryEditorWidgetSorter. * * @param preferences the preferences */ public EntryEditorWidgetSorter( EntryEditorWidgetPreferences preferences ) { this.sortBy = BrowserCoreConstants.SORT_BY_NONE; this.sortOrder = BrowserCoreConstants.SORT_ORDER_NONE; this.preferences = preferences; } /** * Connects this sorter to the given tree viewer. * * @param viewer the viewer */ public void connect( TreeViewer viewer ) { this.viewer = viewer; viewer.setSorter( this ); for ( TreeColumn column : ( ( TreeViewer ) viewer ).getTree().getColumns() ) { column.addSelectionListener( this ); } } /** * Disposes this sorter. */ public void dispose() { viewer = null; preferences = null; } /** * {@inheritDoc} */ public void widgetDefaultSelected( SelectionEvent e ) { } /** * {@inheritDoc} * * Switches the sort property and sort order when clicking the table headers. */ public void widgetSelected( SelectionEvent event ) { if ( ( event.widget instanceof TreeColumn ) && ( viewer != null ) ) { Tree tree = viewer.getTree(); TreeColumn treeColumn = ( ( TreeColumn ) event.widget ); int index = tree.indexOf( treeColumn ); switch ( index ) { case EntryEditorWidgetTableMetadata.KEY_COLUMN_INDEX: if ( sortBy == BrowserCoreConstants.SORT_BY_ATTRIBUTE_DESCRIPTION ) { toggleSortOrder(); } else { // set new sort by sortBy = BrowserCoreConstants.SORT_BY_ATTRIBUTE_DESCRIPTION; sortOrder = BrowserCoreConstants.SORT_ORDER_ASCENDING; } break; case EntryEditorWidgetTableMetadata.VALUE_COLUMN_INDEX: if ( sortBy == BrowserCoreConstants.SORT_BY_VALUE ) { toggleSortOrder(); } else { // set new sort by sortBy = BrowserCoreConstants.SORT_BY_VALUE; sortOrder = BrowserCoreConstants.SORT_ORDER_ASCENDING; } break; default: ; } if ( sortOrder == BrowserCoreConstants.SORT_ORDER_NONE ) { sortBy = BrowserCoreConstants.SORT_BY_NONE; } for ( TreeColumn column : tree.getColumns() ) { column.setImage( null ); } if ( sortOrder == BrowserCoreConstants.SORT_ORDER_ASCENDING ) { treeColumn.setImage( BrowserCommonActivator.getDefault().getImage( BrowserCommonConstants.IMG_SORT_ASCENDING ) ); } else if ( sortOrder == BrowserCoreConstants.SORT_ORDER_DESCENDING ) { treeColumn.setImage( BrowserCommonActivator.getDefault().getImage( BrowserCommonConstants.IMG_SORT_DESCENDING ) ); } viewer.refresh(); } } /** * Rotate the sort order. If it was none, change it to ascending. If it was * ascending, change it to descending, and if it was descending, change it to none. */ private void toggleSortOrder() { switch ( sortOrder ) { case BrowserCoreConstants.SORT_ORDER_NONE : sortOrder = BrowserCoreConstants.SORT_ORDER_ASCENDING; break; case BrowserCoreConstants.SORT_ORDER_ASCENDING : sortOrder = BrowserCoreConstants.SORT_ORDER_DESCENDING; break; case BrowserCoreConstants.SORT_ORDER_DESCENDING : sortOrder = BrowserCoreConstants.SORT_ORDER_NONE; break; } } /** * {@inheritDoc} */ public void sort( final Viewer viewer, Object[] elements ) { Arrays.sort( elements, new Comparator<Object>() { public int compare( Object a, Object b ) { return EntryEditorWidgetSorter.this.compare( viewer, a, b ); } } ); } /** * {@inheritDoc} */ public int compare( Viewer viewer, Object o1, Object o2 ) { // check o1 IAttribute attribute1 = null; IValue value1 = null; if ( o1 instanceof IAttribute ) { attribute1 = ( IAttribute ) o1; } else if ( o1 instanceof IValue ) { value1 = ( IValue ) o1; attribute1 = value1.getAttribute(); } // check o2 IAttribute attribute2 = null; IValue value2 = null; if ( o2 instanceof IAttribute ) { attribute2 = ( IAttribute ) o2; } else if ( o2 instanceof IValue ) { value2 = ( IValue ) o2; attribute2 = value2.getAttribute(); } // compare if ( value1 != null && value2 != null ) { if ( getSortByOrDefault() == BrowserCoreConstants.SORT_BY_ATTRIBUTE_DESCRIPTION ) { if ( value1.getAttribute() != value2.getAttribute() ) { return compareAttributes( value1.getAttribute(), value2.getAttribute() ); } else { return compareValues( value1, value2 ); } } else if ( getSortByOrDefault() == BrowserCoreConstants.SORT_BY_VALUE ) { return compareValues( value1, value2 ); } else { return equal(); } } else if ( ( attribute1 != null ) && ( attribute2 != null ) ) { return compareAttributes( attribute1, attribute2 ); } else { return equal(); } } /** * Compares attribute kind or description. * * @param attribute1 the attribute1 * @param attribute2 the attribute2 * * @return the compare result */ private int compareAttributes( IAttribute attribute1, IAttribute attribute2 ) { if ( this.sortOrder == BrowserCoreConstants.SORT_ORDER_NONE ) { if ( preferences == null || preferences.isObjectClassAndMustAttributesFirst() ) { if ( attribute1.isObjectClassAttribute() ) { return lessThan(); } else if ( attribute2.isObjectClassAttribute() ) { return greaterThan(); } if ( attribute1.isMustAttribute() && !attribute2.isMustAttribute() ) { return lessThan(); } else if ( attribute2.isMustAttribute() && !attribute1.isMustAttribute() ) { return greaterThan(); } } if ( ( preferences == null ) || preferences.isOperationalAttributesLast() ) { if ( attribute1.isOperationalAttribute() && !attribute2.isOperationalAttribute() ) { return greaterThan(); } else if ( attribute2.isOperationalAttribute() && !attribute1.isOperationalAttribute() ) { return lessThan(); } } } return compare( attribute1.getDescription(), attribute2.getDescription() ); } /** * Compares values. * * @param value1 the value1 * @param value2 the value2 * * @return the compare result */ private int compareValues( IValue value1, IValue value2 ) { if ( value1.isEmpty() || value2.isEmpty() ) { if ( !value1.isEmpty() ) { return greaterThan(); } else if ( !value2.isEmpty() ) { return lessThan(); } else { return equal(); } } else { return compare( value1.getStringValue(), value2.getStringValue() ); } } /** * Gets the current sort order or the default sort order from the preferences . * * @return the current sort order or default sort order */ private int getSortOrderOrDefault() { if ( preferences == null ) { return BrowserCoreConstants.SORT_ORDER_ASCENDING; } else if ( sortOrder == BrowserCoreConstants.SORT_ORDER_NONE ) { return preferences.getDefaultSortOrder(); } else { return sortOrder; } } /** * Gets the current sort property or the default sort property from the preferences . * * @return the current sort property or default sort property */ private int getSortByOrDefault() { if ( preferences == null ) { return BrowserCoreConstants.SORT_BY_ATTRIBUTE_DESCRIPTION; } else if ( sortBy == BrowserCoreConstants.SORT_BY_NONE ) { return preferences.getDefaultSortBy(); } else { return sortBy; } } /** * Returns +1 or -1, depending on the sort order. * * @return +1 or -1, depending on the sort order */ private int lessThan() { if ( getSortOrderOrDefault() == BrowserCoreConstants.SORT_ORDER_ASCENDING ) { return -1; } else { return 1; } } /** * Returns 0. * * @return 0 */ private int equal() { return 0; } /** * Returns +1 or -1, depending on the sort order. * * @return +1 or -1, depending on the sort order */ private int greaterThan() { if ( getSortOrderOrDefault() == BrowserCoreConstants.SORT_ORDER_ASCENDING ) { return 1; } else { return -1; } } /** * Compares the two strings using the Strings's compareToIgnoreCase method, * pays attention for the sort order. * * @param s1 the first string to compare * @param s2 the second string to compare * @return a negative integer, zero, or a positive integer * @see java.lang.String#compareToIgnoreCase(String) */ private int compare( String s1, String s2 ) { if ( getSortOrderOrDefault() == BrowserCoreConstants.SORT_ORDER_ASCENDING ) { return s1.compareToIgnoreCase( s2 ); } else { return s2.compareToIgnoreCase( s1 ); } } }