001package org.unix4j.util.sort;
002
003import java.text.Collator;
004import java.util.Comparator;
005
006import org.unix4j.line.Line;
007import org.unix4j.util.sort.TrimBlanksStringComparator.Mode;
008
009/**
010 * Comparator for a {@link Line} without line ending; forwards the comparison of
011 * the content string to a delegate string comparator. Some constants exist for
012 * common line comparators.
013 */
014public class LineComparator implements Comparator<Line> {
015
016        private final Comparator<? super String> comparator;
017
018        /**
019         * Constructor for a line comparator that uses the specified
020         * {@code comparator} to compare the {@link Line#getContent() content}
021         * string of the line.
022         * 
023         * @param comparator
024         *            the comparator used to compare the line content string
025         */
026        private LineComparator(Comparator<? super String> comparator) {
027                this.comparator = comparator;
028        }
029
030        @Override
031        public int compare(Line line1, Line line2) {
032                return comparator.compare(line1.getContent(), line2.getContent());
033        }
034        
035        /**
036         * Line comparator using case sensitive comparison based on the current
037         * local's collation order.
038         */
039        public static final LineComparator COLLATOR = new LineComparator(getCollator(false, false));
040
041        /**
042         * Line comparator using case insensitive comparison based on the current
043         * local's collation order.
044         */
045        public static final LineComparator COLLATOR_IGNORE_CASE = new LineComparator(getCollator(true, false));
046
047        /**
048         * Line comparator using case sensitive comparison based on the current
049         * local's collation order, ignoring leading blanks (spaces and tabs) in the
050         * content string of the line.
051         */
052        public static final LineComparator COLLATOR_IGNORE_LEADING_BLANKS = new LineComparator(getCollator(false, true));
053
054        /**
055         * Line comparator using case insensitive comparison based on the current
056         * local's collation order, ignoring leading blanks (spaces and tabs) in the
057         * content string of the line.
058         */
059        public static final LineComparator COLLATOR_IGNORE_CASE_AND_LEADING_BLANKS = new LineComparator(getCollator(true, true));
060
061        private static Comparator<? super String> getCollator(boolean ignoreCase, boolean ignoreLeadingBlanks) {
062                final Collator collator = Collator.getInstance();
063                if (ignoreCase) {
064                        collator.setStrength(Collator.SECONDARY);
065                }
066                if (ignoreLeadingBlanks) {
067                        return new TrimBlanksStringComparator(Mode.Leading, collator);
068                }
069                return collator;
070        };
071}