blob: 97f615852ff618e54f23f0809cfffac5c855dbfc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.wst.server.ui.internal.viewers;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.wst.server.core.IRuntimeType;
import org.eclipse.wst.server.core.IServerType;
/**
* Class used to sort categories, runtime types, and server types in the
* New wizards.
*/
public class DefaultViewerSorter extends ViewerSorter {
public static class Version implements Comparable {
private static final String SEPARATORS = ".,";
private final String[] segments;
private Version(String[] segments) {
this.segments = segments;
}
public static Version parseVersion(String version) {
List<String> list = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(version, SEPARATORS, false);
while (st.hasMoreTokens())
list.add(st.nextToken());
String[] s = new String[list.size()];
list.toArray(s);
return new Version(s);
}
private int compareTo(String s1, String s2) {
try {
int i1 = Integer.parseInt(s1);
int i2 = Integer.parseInt(s2);
if (i1 == i2)
return 0;
if (i1 > i2)
return 1;
return -1;
} catch (Exception e) {
// ignore
}
return s1.compareTo(s2);
}
public int compareTo(Object object) {
if (object == this)
return 0;
Version other = (Version) object;
int i = 0;
while (i < segments.length && i < other.segments.length) {
String s1 = segments[i];
String s2 = other.segments[i];
int c = compareTo(s1, s2);
if (c != 0)
return c;
i++;
}
if (i == segments.length && i == other.segments.length)
return 0;
if (i == segments.length)
return -1;
return 1;
}
}
/**
* @see ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
public int compare(Viewer viewer, Object o1, Object o2) {
if (o1 instanceof AbstractTreeContentProvider.TreeElement)
o1 = ((AbstractTreeContentProvider.TreeElement) o1).text;
if (o2 instanceof AbstractTreeContentProvider.TreeElement)
o2 = ((AbstractTreeContentProvider.TreeElement) o2).text;
// filter out strings
if (o1 instanceof String && o2 instanceof String)
return compareCategories((String) o1, (String) o2);
if (o1 instanceof String)
return -1;
if (o2 instanceof String)
return 1;
if (o1 instanceof IRuntimeType && o2 instanceof IRuntimeType)
return compareRuntimeTypes((IRuntimeType) o1, (IRuntimeType) o2);
if (o1 instanceof IServerType && o2 instanceof IServerType)
return compareServerTypes((IServerType) o1, (IServerType) o2);
return 0;
}
/**
* Sort two category names.
*
* @param s1 the first category
* @param s2 the second category
* @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
*/
protected static int compareCategories(String s1, String s2) {
try {
Version v1 = Version.parseVersion(s1);
Version v2 = Version.parseVersion(s2);
return v1.compareTo(v2);
} catch (NumberFormatException nfe) {
// ignore
}
return s1.compareTo(s2);
}
/**
* Returns <code>true</code> if the two items are in the same 'family', and
* <code>false</code> otherwise.
*
* @param s1 - first name
* @param v1 - first version
* @param s2 - second name
* @param v2 - second version
* @return <code>true</code> if the two items are in the same 'family', and
* <code>false</code> otherwise
*/
protected static boolean isSameFamily(String s1, String v1, String s2, String v2) {
if (s1 == null || s2 == null)
return false;
if (v1 != null) {
int ind = s1.indexOf(v1);
if (ind >= 0)
s1 = s1.substring(0, ind) + s1.substring(ind+v1.length());
}
if (v2 != null) {
int ind = s2.indexOf(v2);
if (ind >= 0)
s2 = s2.substring(0, ind) + s2.substring(ind+v2.length());
}
return (s1.equals(s2));
}
protected static int compareVersions(String s1, String s2) {
Version v1 = Version.parseVersion(s1);
Version v2 = Version.parseVersion(s2);
return v1.compareTo(v2);
}
/**
* Sort two runtime types.
*
* @param r1 the first runtime type
* @param r2 the second runtime type
* @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
*/
protected static int compareRuntimeTypes(IRuntimeType r1, IRuntimeType r2) {
if (isSameFamily(r1.getName(), r1.getVersion(), r2.getName(), r2.getVersion()))
return compareVersions(r1.getVersion(), r2.getVersion());
return r1.getName().compareToIgnoreCase(r2.getName());
}
/**
* Sort two server types.
*
* @param s1 the first server type
* @param s2 the second server type
* @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
*/
protected static int compareServerTypes(IServerType s1, IServerType s2) {
IRuntimeType r1 = s1.getRuntimeType();
IRuntimeType r2 = s2.getRuntimeType();
if (r1 != null && r2 != null) {
if (isSameFamily(s1.getName(), r1.getVersion(), s2.getName(), r2.getVersion()))
return compareVersions(r1.getVersion(), r2.getVersion());
}
return s1.getName().compareToIgnoreCase(s2.getName());
}
}