001package org.unix4j.unix.cat;
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.LineProcessor;
008import org.unix4j.processor.RedirectInputLineProcessor;
009import org.unix4j.unix.Cat;
010import org.unix4j.util.FileUtil;
011
012import java.io.File;
013import java.util.Arrays;
014import java.util.List;
015
016/**
017 * Implementation of the {@link Cat cat} command.
018 */
019class CatCommand extends AbstractCommand<CatArguments> {
020        public CatCommand(CatArguments arguments) {
021                super(Cat.NAME, arguments);
022        }
023
024        @Override
025        public LineProcessor execute(ExecutionContext context, final LineProcessor output) {
026                final CatArguments args = getArguments(context);
027
028                // input from files?
029                if (args.isFilesSet()) {
030                        final List<FileInput> inputs = FileInput.multiple(args.getFiles());
031                        return getFileInputProcessor(inputs, context, output, args);
032                } else if (args.isPathsSet()) {
033                        final List<File> files = FileUtil.expandFiles(context.getCurrentDirectory(), args.getPaths());
034                        final List<FileInput> inputs = FileInput.multiple(files);
035                        return getFileInputProcessor(inputs, context, output, args);
036                } else if (args.isInputsSet()) {
037                        final List<Input> inputs = Arrays.asList(args.getInputs());
038                        return getFileInputProcessor(inputs, context, output, args);
039                }
040
041                // standard input
042                return getStandardInputProcessor(context, output, args);
043        }
044
045        private LineProcessor getStandardInputProcessor(ExecutionContext context, LineProcessor output, CatArguments args) {
046                final LineProcessor printer;
047                if (args.isNumberLines() || args.isNumberNonBlankLines()) {
048                        printer = new NumberLinesProcessor(this, context, output);
049                } else {
050                        printer = output;
051                }
052                if (args.isSqueezeEmptyLines()) {
053                        return new SqueezeEmptyLinesProcessor(this, context, printer);
054                }
055                return new CatProcessor(this, context, printer);
056        }
057
058        private LineProcessor getFileInputProcessor(List<? extends Input> inputs, ExecutionContext context, LineProcessor output, CatArguments args) {
059                final LineProcessor standardInputProcessor = getStandardInputProcessor(context, output, args); 
060                return new RedirectInputLineProcessor(inputs, standardInputProcessor);
061        }
062}