001package org.unix4j.unix.from;
002
003import java.io.File;
004import java.util.List;
005
006import org.unix4j.command.AbstractCommand;
007import org.unix4j.context.ExecutionContext;
008import org.unix4j.io.FileInput;
009import org.unix4j.io.Input;
010import org.unix4j.line.Line;
011import org.unix4j.processor.LineProcessor;
012import org.unix4j.unix.From;
013import org.unix4j.util.FileUtil;
014
015/**
016 * Implementation of the pseudo {@link From from} command used for input
017 * redirection.
018 */
019class FromCommand extends AbstractCommand<FromArguments> {
020        public FromCommand(FromArguments arguments) {
021                super(From.NAME, arguments);
022        }
023
024        @Override
025        public LineProcessor execute(ExecutionContext context, final LineProcessor output) {
026                final FromArguments args = getArguments(context);
027                final Input input;
028                
029                if (args.isPathSet()) {
030                        final String path = args.getPath();
031                        final List<File> files = FileUtil.expandFiles(context.getCurrentDirectory(), path);
032                        if (files.size() == 1) {
033                                input = new FileInput(files.get(0));
034                        } else {
035                                throw new IllegalArgumentException("expected one file, but found " + files.size() + " for path: " + path);
036                        }
037                } else if (args.isInputSet()) {
038                        input = args.getInput();
039                } else {
040                        throw new IllegalStateException("neither path nor input argument has been specified");
041                }
042                return new LineProcessor() {
043                        @Override
044                        public boolean processLine(Line line) {
045                                return false;// we ARE the input, so we don't want any more
046                                                                // lines
047                        }
048
049                        @Override
050                        public void finish() {
051                                for (final Line line : input) {
052                                        if (!output.processLine(line)) {
053                                                break;
054                                        }
055                                }
056                                output.finish();
057                        }
058                };
059        }
060}