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