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