1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/*******************************************************************************
* Copyright (c) 2011, 2012 Wind River Systems, Inc. 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:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.tcf.te.tcf.processes.ui.editor.tree.columns;
import java.io.Serializable;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNode;
import org.eclipse.tcf.te.tcf.processes.ui.navigator.runtime.LabelProviderDelegate;
/**
* The comparator for the tree column "name".
*/
public class ProcessComparator implements Comparator<IProcessContextNode> , Serializable {
private static final long serialVersionUID = 1L;
private static LabelProvider labelProvider = new LabelProviderDelegate();
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare(IProcessContextNode node1, IProcessContextNode node2) {
if (node1 == null && node2 == null) return 0;
if (node1 != null && node2 == null) return 1;
if (node1 == null && node2 != null) return -1;
// Get the labels
String text1 = node1 == null ? null : labelProvider.getText(node1);
String text2 = node2 == null ? null : labelProvider.getText(node2);
// Normalize labels
if (text1 == null) text1 = ""; //$NON-NLS-1$
if (text2 == null) text2 = ""; //$NON-NLS-1$
// The tree sorts not strictly alphabetical. First comes entries starting with numbers,
// second entries starting with uppercase and than all the rest. Additional, if a label
// contains
// uppercase characters, it is sorted in before any labels being lowercase only.
if (text1.length() > 0 && text2.length() > 0) {
// Get the first characters of both
char c1 = text1.charAt(0);
char c2 = text2.charAt(0);
if (Character.isDigit(c1) || Character.isDigit(c2)) {
// Check on the differences. If both are digits, the standard compare will do it
if (Character.isDigit(c1) && !Character.isDigit(c2)) return -1;
if (!Character.isDigit(c1) && Character.isDigit(c2)) return 1;
}
if (Character.isUpperCase(c1) || Character.isUpperCase(c2)) {
// Check on the differences. If both are uppercase characters, the standard compare
// will do it
if (Character.isUpperCase(c1) && !Character.isUpperCase(c2)) return -1;
if (!Character.isUpperCase(c1) && Character.isUpperCase(c2)) return 1;
}
Matcher m1 = Pattern.compile("(\\D+)(\\d+)").matcher(text1); //$NON-NLS-1$
Matcher m2 = Pattern.compile("(\\D+)(\\d+)").matcher(text2); //$NON-NLS-1$
if (m1.matches() && m2.matches()) {
String p11 = m1.group(1);
String p12 = m1.group(2);
String p21 = m2.group(1);
String p22 = m2.group(2);
if (p11 != null && p11.equals(p21)) {
// Compare the second parts as number
try {
int result = 0;
long l1 = Long.parseLong(p12);
long l2 = Long.parseLong(p22);
if (l1 > l2) result = 1;
if (l1 < l2) result = -1;
return result;
}
catch (NumberFormatException e) { /* ignored on purpose */
}
}
}
if (text1.matches(".*[A-Z]+.*") || text2.matches(".*[A-Z]+.*")) { //$NON-NLS-1$ //$NON-NLS-2$
if (text1.matches(".*[A-Z]+.*") && !text2.matches(".*[A-Z]+.*")) return -1; //$NON-NLS-1$ //$NON-NLS-2$
if (!text1.matches(".*[A-Z]+.*") && text2.matches(".*[A-Z]+.*")) return 1; //$NON-NLS-1$ //$NON-NLS-2$
// Additionally, it even depends on the position of the first uppercase
// character if both strings contains them :-(
int minLength = Math.min(text1.length(), text2.length());
for (int i = 0; i < minLength; i++) {
char ch1 = text1.charAt(i);
char ch2 = text2.charAt(i);
if (Character.isUpperCase(ch1) && !Character.isUpperCase(ch2)) return -1;
if (!Character.isUpperCase(ch1) && Character.isUpperCase(ch2)) return 1;
// If both are uppercase, we break the loop and compare as usual
if (Character.isUpperCase(ch1) && Character.isUpperCase(ch2)) break;
}
}
}
return text1.compareTo(text2);
}
}
|