001package org.unix4j.unix.grep;
002
003import org.unix4j.context.ExecutionContext;
004import org.unix4j.io.FileInput;
005import org.unix4j.io.Input;
006import org.unix4j.line.Line;
007import org.unix4j.line.SimpleLine;
008import org.unix4j.processor.InputProcessor;
009import org.unix4j.processor.LineProcessor;
010import org.unix4j.util.Counter;
011
012/**
013 * Counts the matching lines and writes the count and the file name to the
014 * output. The matching operation is delegated to the {@link LineMatcher} passed
015 * to the constructor.
016 */
017final class WriteMatchingLinesInputProcessor implements InputProcessor {
018
019        private final ExecutionContext context;
020        private final LineMatcher matcher;
021        private final Counter lineCounter = new Counter();
022
023        public WriteMatchingLinesInputProcessor(GrepCommand command, ExecutionContext context, LineMatcher matcher) {
024                this.context = context;
025                this.matcher = matcher;
026        }
027
028        @Override
029        public void begin(Input input, LineProcessor output) {
030                lineCounter.reset();
031        }
032        
033        @Override
034        public boolean processLine(Input input, Line line, LineProcessor output) {
035                lineCounter.increment();
036                if (matcher.matches(line)) {
037                        final String fileInfo = input instanceof FileInput ? ((FileInput)input).getFileInfo(context.getCurrentDirectory()) : input.toString();
038                        return output.processLine(new SimpleLine(
039                                        fileInfo + ":" + lineCounter.getCount() + ":" + line.getContent(), line.getLineEnding()
040                        ));
041                }
042                return true;//this line is not a match, but we still want the next line
043        }
044
045        @Override
046        public void finish(Input input, LineProcessor output) {
047                lineCounter.reset();
048                output.finish();
049        }
050}