001package org.unix4j.unix.wc;
002
003import java.util.List;
004import java.util.NavigableMap;
005import java.util.TreeMap;
006
007import org.unix4j.context.ExecutionContext;
008import org.unix4j.io.FileInput;
009import org.unix4j.io.Input;
010import org.unix4j.line.Line;
011import org.unix4j.processor.LineProcessor;
012
013/**
014 * Input processor for line, word and char count for multiple input files.
015 */
016class WcMultipleFilesProcessor implements LineProcessor {
017        private final ExecutionContext context;
018        private final NavigableMap<String, Counters> inputCounters;
019        private final Counters totals;
020    private final WcArguments args;
021    private final List<FileInput> inputs;
022    private final LineProcessor output;
023    private Counters currentInputCounter;
024
025    public WcMultipleFilesProcessor(final ExecutionContext context, final List<FileInput> inputs, final LineProcessor output, WcArguments args) {
026        this.context = context;
027        this.inputCounters = new TreeMap<String, Counters>();
028        this.currentInputCounter = new Counters(args);
029        this.totals = new Counters(args);
030        this.args = args;
031        this.inputs = inputs;
032        this.output = output;
033        }
034
035    @Override
036    public boolean processLine(Line line) {
037        return false; // we want no input, we have it already
038    }
039
040    @Override
041    public void finish() {
042        for (final Input input: inputs) {
043            for (final Line line : input) {
044                currentInputCounter.update(line);
045            }
046            finishSingleInput(input);
047        }
048        writeOutput();
049    }
050
051        private void finishSingleInput(Input input) {
052                final String fileInfo = input instanceof FileInput ? ((FileInput)input).getFileInfo(context.getCurrentDirectory()) : input.toString();
053                totals.updateTotal(currentInputCounter);
054        inputCounters.put(fileInfo, currentInputCounter);
055        currentInputCounter = new Counters(args);
056        }
057
058        private void writeOutput() {
059        int fixedWidthOfColumnsInOutput = totals.getFixedWidthOfColumnsInOutput();
060        for(final String fileInfo: inputCounters.keySet()){
061            final Counters inputCounter = inputCounters.get(fileInfo);
062            inputCounter.writeCountsLineWithFileInfo(output, fileInfo, fixedWidthOfColumnsInOutput);
063        }
064        totals.writeCountsLineWithFileInfo(output, "total", fixedWidthOfColumnsInOutput);
065        }
066}