001package org.unix4j.unix.wc; 002 003import org.unix4j.context.ExecutionContext; 004import org.unix4j.io.FileInput; 005import org.unix4j.io.Input; 006import org.unix4j.line.Line; 007import org.unix4j.processor.LineProcessor; 008 009import java.util.List; 010import java.util.NavigableMap; 011import java.util.TreeMap; 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<? extends Input> inputs; 022 private final LineProcessor output; 023 private Counters currentInputCounter; 024 025 public WcMultipleFilesProcessor(final ExecutionContext context, final List<? extends Input> inputs, final LineProcessor output, WcArguments args) { 026 this.context = context; 027 this.inputCounters = new TreeMap<>(); 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 closeInputs(); 050 } 051 052 private void finishSingleInput(Input input) { 053 final String fileInfo = input instanceof FileInput ? ((FileInput)input).getFileInfo(context.getCurrentDirectory()) : input.toString(); 054 totals.updateTotal(currentInputCounter); 055 inputCounters.put(fileInfo, currentInputCounter); 056 currentInputCounter = new Counters(args); 057 } 058 059 private void writeOutput() { 060 int fixedWidthOfColumnsInOutput = totals.getFixedWidthOfColumnsInOutput(); 061 for(final String fileInfo: inputCounters.keySet()){ 062 final Counters inputCounter = inputCounters.get(fileInfo); 063 inputCounter.writeCountsLineWithFileInfo(output, fileInfo, fixedWidthOfColumnsInOutput); 064 } 065 totals.writeCountsLineWithFileInfo(output, "total", fixedWidthOfColumnsInOutput); 066 } 067 068 private void closeInputs() { 069 for (final Input input : inputs) { 070 input.close(); 071 } 072 } 073}