aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/sorting/NameComparator.java
blob: fb984920522ac1e3f716ad1fc2f5c7e0e19d748a (plain)
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
package cgeo.geocaching.sorting;

import cgeo.geocaching.cgCache;

import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * sorts caches by name
 *
 */
public class NameComparator extends AbstractCacheComparator {

    private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");

    @Override
    protected boolean canCompare(cgCache cache1, cgCache cache2) {
        return StringUtils.isNotBlank(cache1.name) && StringUtils.isNotBlank(cache2.name);
    }

    @Override
    protected int compareCaches(cgCache cache1, cgCache cache2) {
        // if the caches have a common prefix followed by a number, sort by the numerical value
        // so 2 is before 11, although "11" comes before "2"
        final String prefix = StringUtils.getCommonPrefix(cache1.name, cache2.name);
        if (StringUtils.length(prefix) > 0) {
            final String remaining1 = cache1.name.substring(prefix.length()).trim();
            if (remaining1.length() > 0 && Character.isDigit(remaining1.charAt(0))) {
                final String remaining2 = cache2.name.substring(prefix.length()).trim();
                if (remaining2.length() > 0 && Character.isDigit(remaining2.charAt(0))) {
                    final Integer number1 = getNumber(remaining1);
                    final Integer number2 = getNumber(remaining2);
                    return number1.compareTo(number2);
                }
            }
        }
        return cache1.name.compareToIgnoreCase(cache2.name);
    }

    private static Integer getNumber(final String string) {
        Matcher matcher = NUMBER_PATTERN.matcher(string);
        if (matcher.find()) {
            return Integer.valueOf(matcher.group());
        }
        return 0;
    }
}