001package org.unix4j.util.sort;
002
003import java.util.Comparator;
004import java.util.Objects;
005
006/**
007 * Comparator for strings considering only blanks and alphanumeric characters.
008 */
009public class DictionaryStringComparator implements Comparator<String> {
010
011
012        private final Comparator<? super String> comparator;
013
014        /**
015         * Constructor with delegate comparator comparing strings containing only
016         * blanks and alphanumeric characters.
017         *
018         * @param comparator the delegate comparator
019     */
020        public DictionaryStringComparator(final Comparator<? super String> comparator) {
021                this.comparator = Objects.requireNonNull(comparator);
022        }
023
024        @Override
025        public int compare(String s1, String s2) {
026                return comparator.compare(dictionaryString(s1), dictionaryString(s2));
027        }
028
029        private static String dictionaryString(String s) {
030                final int len = s.length();
031                for (int i = 0; i < len; i++) {
032                        if (!isBlankOrAlphaNumeric(s.charAt(i))) {
033                                return convertToDictionaryString(s);
034                        }
035                }
036                return s;
037        }
038
039        private static String convertToDictionaryString(String s) {
040                final int len = s.length();
041                final StringBuilder sb = new StringBuilder(len);
042                for (int i = 0; i < len; i++) {
043                        final char ch = s.charAt(i);
044                        if (isBlankOrAlphaNumeric(ch)) {
045                                sb.append(ch);
046                        }
047                }
048                return sb.toString();
049        }
050
051        private static boolean isBlankOrAlphaNumeric(char ch) {
052                return Character.isWhitespace(ch) || Character.isDigit(ch) || Character.isLetter(ch);
053        }
054}