001package org.unix4j.unix.sort; 002 003import org.unix4j.command.AbstractCommand; 004import org.unix4j.context.ExecutionContext; 005import org.unix4j.io.FileInput; 006import org.unix4j.io.Input; 007import org.unix4j.processor.DefaultInputProcessor; 008import org.unix4j.processor.InputProcessor; 009import org.unix4j.processor.LineProcessor; 010import org.unix4j.processor.MultipleInputLineProcessor; 011import org.unix4j.processor.RedirectInputLineProcessor; 012import org.unix4j.unix.Sort; 013import org.unix4j.util.FileUtil; 014 015import java.io.File; 016import java.util.Arrays; 017import java.util.Collections; 018import java.util.List; 019 020/** 021 * Implementation of the {@link Sort sort} command. 022 */ 023class SortCommand extends AbstractCommand<SortArguments> { 024 025 public SortCommand(SortArguments arguments) { 026 super(Sort.NAME, arguments); 027 } 028 029 @Override 030 public LineProcessor execute(ExecutionContext context, LineProcessor output) { 031 final SortArguments args = getArguments(context); 032 033 if (args.isMerge()) { 034 return getMergeProcessor(context, output, args); 035 } else if (args.isCheck()) { 036 return getCheckProcessor(context, output, args); 037 } else { 038 return getSortProcessor(context, output, args); 039 } 040 } 041 042 private LineProcessor getSortProcessor(ExecutionContext context, LineProcessor output, SortArguments args) { 043 final LineProcessor standardInputProcessor; 044 if (args.isUnique()) { 045 standardInputProcessor = new UniqueSortProcessor(this, context, output); 046 } else { 047 standardInputProcessor = new SortProcessor(this, context, output); 048 } 049 //input from file? 050 if (args.isFilesSet()) { 051 final List<FileInput> inputs = FileInput.multiple(args.getFiles()); 052 return new RedirectInputLineProcessor(inputs, standardInputProcessor); 053 } else if (args.isPathsSet()) { 054 final List<File> files = FileUtil.expandFiles(context.getCurrentDirectory(), args.getPaths()); 055 final List<FileInput> inputs = FileInput.multiple(files); 056 return new RedirectInputLineProcessor(inputs, standardInputProcessor); 057 } else if (args.isInputsSet()) { 058 final List<Input> inputs = Arrays.asList(args.getInputs()); 059 return new RedirectInputLineProcessor(inputs, standardInputProcessor); 060 } 061 return standardInputProcessor; 062 } 063 064 private LineProcessor getMergeProcessor(ExecutionContext context, LineProcessor output, SortArguments args) { 065 //input from file? 066 if (args.isFilesSet()) { 067 final List<FileInput> inputs = FileInput.multiple(args.getFiles()); 068 return new MergeProcessor(this, context, output, inputs); 069 } else if (args.isPathsSet()) { 070 final List<File> files = FileUtil.expandFiles(context.getCurrentDirectory(), args.getPaths()); 071 final List<FileInput> inputs = FileInput.multiple(files); 072 return new MergeProcessor(this, context, output, inputs); 073 } else if (args.isInputsSet()) { 074 final List<Input> inputs = Arrays.asList(args.getInputs()); 075 return new MergeProcessor(this, context, output, inputs); 076 } else { 077 final List<Input> empty = Collections.emptyList(); 078 return new MergeProcessor(this, context, output, empty); 079 } 080 } 081 082 private LineProcessor getCheckProcessor(ExecutionContext context, LineProcessor output, SortArguments args) { 083 final CheckProcessor standardInputProcessor = new CheckProcessor(this, context, output); 084 //input from file? 085 List<? extends Input> inputs = null; 086 if (args.isFilesSet()) { 087 inputs = FileInput.multiple(args.getFiles()); 088 } else if (args.isPathsSet()) { 089 final List<File> files = FileUtil.expandFiles(context.getCurrentDirectory(), args.getPaths()); 090 inputs = FileInput.multiple(files); 091 } else if (args.isInputsSet()) { 092 inputs = Arrays.asList(args.getInputs()); 093 } 094 if (inputs != null) { 095 if (inputs.size() < 2) { 096 return new RedirectInputLineProcessor(inputs, standardInputProcessor); 097 } 098 final InputProcessor resetPerFileProcessor = new DefaultInputProcessor() { 099 @Override 100 public void finish(Input input, LineProcessor output) { 101 standardInputProcessor.reset(); 102 } 103 }; 104 return new MultipleInputLineProcessor(inputs, resetPerFileProcessor, standardInputProcessor); 105 } 106 return standardInputProcessor; 107 } 108 109}