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}