001package org.unix4j.unix.uniq;
002
003import org.unix4j.context.ExecutionContext;
004import org.unix4j.line.Line;
005import org.unix4j.processor.LineProcessor;
006
007/**
008 * Line processors implementing the actual uniq command execution for the case
009 * when the {@link UniqOption#global global} option is NOT selected. The actual
010 * processors are member classes of this abstract base class.
011 */
012abstract class AdjacentProcessor extends UniqProcessor {
013        protected Line curLine = null;
014
015        public AdjacentProcessor(UniqCommand command, ExecutionContext context, LineProcessor output) {
016                super(command, context, output);
017        }
018
019        /**
020         * Line processor implementing the actual uniq command execution for the
021         * case when no option is selected.
022         */
023        public static class Normal extends AdjacentProcessor {
024                public Normal(UniqCommand command, ExecutionContext context, LineProcessor output) {
025                        super(command, context, output);
026                }
027
028                @Override
029                protected boolean processLine(Line line, LineProcessor output) {
030                        if (curLine == null || !curLine.equals(line)) {
031                                output.processLine(line);
032                                curLine = line;
033                        }
034                        return true;// we want all input
035                }
036
037                @Override
038                public void finish() {
039                        curLine = null;
040                        getOutput().finish();
041                }
042        }
043
044        /**
045         * Abstract base class for member classes {@link UniqueOnly},
046         * {@link DuplicateOnly} and {@link Count}
047         */
048        abstract protected static class UniqueDuplicateCount extends AdjacentProcessor {
049                private long curCount = 0;
050
051                public UniqueDuplicateCount(UniqCommand command, ExecutionContext context, LineProcessor output) {
052                        super(command, context, output);
053                }
054
055                @Override
056                protected boolean processLine(Line line, LineProcessor output) {
057                        if (curLine == null || !curLine.equals(line)) {
058                                writeLine(curLine, curCount, output);
059                                curCount = 1;
060                                curLine = line;
061                        } else {
062                                curCount++;
063                        }
064                        return true;// we want all input
065                }
066
067                @Override
068                public void finish() {
069                        final LineProcessor output = getOutput();
070                        writeLine(curLine, curCount, output);
071                        curCount = 0;
072                        curLine = null;
073                        output.finish();
074                }
075
076                abstract protected void writeLine(Line line, long count, LineProcessor output);
077        }
078
079        /**
080         * Line processor implementing the actual uniq command execution for the
081         * case when only the {@link UniqOption#uniqueOnly uniqueOnly} option is
082         * selected.
083         */
084        public static class UniqueOnly extends UniqueDuplicateCount {
085                public UniqueOnly(UniqCommand command, ExecutionContext context, LineProcessor output) {
086                        super(command, context, output);
087                }
088
089                @Override
090                protected void writeLine(Line line, long count, LineProcessor output) {
091                        if (count == 1) {
092                                output.processLine(line);
093                        }
094                }
095        }
096
097        /**
098         * Line processor implementing the actual uniq command execution for the
099         * case when only the {@link UniqOption#duplicatedOnly duplicatedOnly}
100         * option is selected.
101         */
102        public static class DuplicateOnly extends UniqueDuplicateCount {
103                public DuplicateOnly(UniqCommand command, ExecutionContext context, LineProcessor output) {
104                        super(command, context, output);
105                }
106
107                @Override
108                protected void writeLine(Line line, long count, LineProcessor output) {
109                        if (count > 1) {
110                                output.processLine(line);
111                        }
112                }
113        }
114
115        /**
116         * Line processor implementing the actual uniq command execution for the
117         * case when only the {@link UniqOption#count count} option is selected.
118         */
119        public static class Count extends UniqueDuplicateCount {
120                public Count(UniqCommand command, ExecutionContext context, LineProcessor output) {
121                        super(command, context, output);
122                }
123
124                @Override
125                protected void writeLine(Line line, long count, LineProcessor output) {
126                        if (count > 0) {
127                                CountUtil.writeCountLine(line, count, 3, output);
128                        }
129                }
130        }
131
132}