001package jmri.util;
002
003import jmri.NamedBean;
004
005/**
006 * Comparator for JMRI NamedBeans via their User Names.
007 * <p>
008 * If the User Names are both non-null and the {@link AlphanumComparator} tells
009 * them apart, uses that order, otherwise uses the beans' own
010 * {@link NamedBean#compareTo} order. The {@link AlphanumComparator} treats
011 * names such as "Siding 7" and "Siding 07" as equal, so those also fall back to
012 * the beans' own order.
013 *
014 * @param <B> supported type of NamedBean
015 */
016public class NamedBeanUserNameComparator<B extends NamedBean> implements java.util.Comparator<B> {
017
018    public NamedBeanUserNameComparator() {
019    }
020
021    static final AlphanumComparator comparator = new AlphanumComparator();
022
023    @Override
024    public int compare(B n1, B n2) {
025        String s1 = n1.getUserName();
026        String s2 = n2.getUserName();
027
028        // handle both usernames being null or empty
029        if ((s1 == null || s1.isEmpty()) && (s2 == null || s2.isEmpty())) {
030            return n1.compareTo(n2);
031        }
032
033        // if both have user names, compare those
034        if (! (s1 == null || s1.isEmpty()) && ! (s2 == null || s2.isEmpty())) {
035            int result = comparator.compare(s1, s2);
036            if (result == 0) {
037                // the user names don't decide the order, e.g. "Siding 7" and
038                // "Siding 07", or the same user name on beans of different types
039                result = n1.compareTo(n2);
040            }
041            return result;
042        }
043
044        // now must have one with and one without
045        if (s1 == null || s1.isEmpty()) {
046            return +1; // system name always after n2 with user name
047        } else {
048             return -1; // user name always before n2 with only system name
049        }
050    }
051}