001: /*******************************************************************************
002: * Copyright (c) 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.views.navigator;
011:
012: import org.eclipse.core.resources.IContainer;
013: import org.eclipse.core.resources.IResource;
014: import org.eclipse.jface.viewers.Viewer;
015: import org.eclipse.jface.viewers.ViewerComparator;
016:
017: /**
018: * Comparator for viewers that display items of type <code>IResource</code>.
019: * The sorter supports two sort criteria:
020: * <p>
021: * <code>NAME</code>: Folders are given order precedence, followed by files.
022: * Within these two groups resources are ordered by name. All name comparisons
023: * are case-insensitive.
024: * </p>
025: * <p>
026: * <code>TYPE</code>: Folders are given order precedence, followed by files.
027: * Within these two groups resources are ordered by extension. All extension
028: * comparisons are case-insensitive.
029: * </p>
030: * <p>
031: * This class may be instantiated; it is not intended to be subclassed.
032: * </p>
033: *
034: * @since 3.3
035: */
036: public class ResourceComparator extends ViewerComparator {
037:
038: /**
039: * Constructor argument value that indicates to sort items by name.
040: */
041: public final static int NAME = 1;
042:
043: /**
044: * Constructor argument value that indicates to sort items by extension.
045: */
046: public final static int TYPE = 2;
047:
048: private int criteria;
049:
050: /**
051: * Creates a resource sorter that will use the given sort criteria.
052: *
053: * @param criteria the sort criterion to use: one of <code>NAME</code> or
054: * <code>TYPE</code>
055: */
056: public ResourceComparator(int criteria) {
057: super ();
058: this .criteria = criteria;
059: }
060:
061: /**
062: * Returns an integer value representing the relative sort priority of the
063: * given element based on its class.
064: * <p>
065: * <ul>
066: * <li>resources (<code>IResource</code>) - 2</li>
067: * <li>project references (<code>ProjectReference</code>) - 1</li>
068: * <li>everything else - 0</li>
069: * </ul>
070: * </p>
071: *
072: * @param element the element
073: * @return the sort priority (larger numbers means more important)
074: */
075: protected int classComparison(Object element) {
076: if (element instanceof IResource) {
077: return 2;
078: }
079: return 0;
080: }
081:
082: /* (non-Javadoc)
083: * Method declared on ViewerComparator.
084: */
085: public int compare(Viewer viewer, Object o1, Object o2) {
086: //have to deal with non-resources in navigator
087: //if one or both objects are not resources, returned a comparison
088: //based on class.
089: if (!(o1 instanceof IResource && o2 instanceof IResource)) {
090: return compareClass(o1, o2);
091: }
092: IResource r1 = (IResource) o1;
093: IResource r2 = (IResource) o2;
094:
095: if (r1 instanceof IContainer && r2 instanceof IContainer) {
096: return compareNames(r1, r2);
097: } else if (r1 instanceof IContainer) {
098: return -1;
099: } else if (r2 instanceof IContainer) {
100: return 1;
101: } else if (criteria == NAME) {
102: return compareNames(r1, r2);
103: } else if (criteria == TYPE) {
104: return compareTypes(r1, r2);
105: } else {
106: return 0;
107: }
108: }
109:
110: /**
111: * Returns a number reflecting the collation order of the given elements
112: * based on their class.
113: *
114: * @param element1 the first element to be ordered
115: * @param element2 the second element to be ordered
116: * @return a negative number if the first element is less than the
117: * second element; the value <code>0</code> if the first element is
118: * equal to the second element; and a positive number if the first
119: * element is greater than the second element
120: */
121: protected int compareClass(Object element1, Object element2) {
122: return classComparison(element1) - classComparison(element2);
123: }
124:
125: /**
126: * Returns a number reflecting the collation order of the given resources
127: * based on their resource names.
128: *
129: * @param resource1 the first resource element to be ordered
130: * @param resource2 the second resource element to be ordered
131: * @return a negative number if the first element is less than the
132: * second element; the value <code>0</code> if the first element is
133: * equal to the second element; and a positive number if the first
134: * element is greater than the second element
135: */
136: protected int compareNames(IResource resource1, IResource resource2) {
137: return getComparator().compare(resource1.getName(),
138: resource2.getName());
139: }
140:
141: /**
142: * Returns a number reflecting the collation order of the given resources
143: * based on their respective file extensions. Resources with the same file
144: * extension will be collated based on their names.
145: *
146: * @param resource1 the first resource element to be ordered
147: * @param resource2 the second resource element to be ordered
148: * @return a negative number if the first element is less than the
149: * second element; the value <code>0</code> if the first element is
150: * equal to the second element; and a positive number if the first
151: * element is greater than the second element
152: */
153: protected int compareTypes(IResource resource1, IResource resource2) {
154: String ext1 = getExtensionFor(resource1);
155: String ext2 = getExtensionFor(resource2);
156:
157: // Compare extensions. If they're different then return a value that
158: // indicates correct extension ordering. If they're the same then
159: // return a value that indicates the correct NAME ordering.
160: int result = getComparator().compare(ext1, ext2);
161:
162: if (result != 0) {
163: return result;
164: }
165:
166: return compareNames(resource1, resource2);
167: }
168:
169: /**
170: * Returns the sort criteria of this sorter.
171: *
172: * @return the sort criterion: one of <code>NAME</code> or <code>TYPE</code>
173: */
174: public int getCriteria() {
175: return criteria;
176: }
177:
178: /**
179: * Returns the extension portion of the given resource.
180: *
181: * @param resource the resource
182: * @return the file extension, possibily the empty string
183: */
184: private String getExtensionFor(IResource resource) {
185: String ext = resource.getFileExtension();
186: return ext == null ? "" : ext; //$NON-NLS-1$
187: }
188:
189: /**
190: * Sets the sort criteria of this sorter.
191: *
192: * @param criteria the sort criterion:
193: * one of <code>ResourceSorter.NAME</code> or
194: * <code>ResourceSorter.TYPE</code>
195: */
196: public void setCriteria(int criteria) {
197: this.criteria = criteria;
198: }
199: }
|