001package org.unix4j.unix.grep;
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.processor.InputProcessor;
010import org.unix4j.processor.LineProcessor;
011import org.unix4j.processor.MultipleInputLineProcessor;
012import org.unix4j.processor.RedirectInputLineProcessor;
013import org.unix4j.unix.Grep;
014import org.unix4j.util.FileUtil;
015
016/**
017 * Implementation of the {@link Grep grep} command.
018 */
019class GrepCommand extends AbstractCommand<GrepArguments> {
020        public GrepCommand(GrepArguments arguments) {
021                super(Grep.NAME, arguments);
022        }
023
024        @Override
025        public LineProcessor execute(ExecutionContext context, LineProcessor output) {
026                final GrepArguments args = getArguments(context);
027
028                //from file?
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                }
037
038                //from standard input
039                return getStandardInputProcessor(context, output, args);
040        }
041
042        private LineMatcher getMatcher(GrepArguments args) {
043                final LineMatcher matcher;
044                if (args.isFixedStrings()) {
045                        if (args.isWholeLine()) {
046                                matcher = args.isIgnoreCase() ? new FixedStringMatcher.WholeLineIgnoreCase(args) : new FixedStringMatcher.WholeLine(args);
047                        } else {
048                                matcher = args.isIgnoreCase() ? new FixedStringMatcher.IgnoreCase(args) : new FixedStringMatcher.Standard(args);
049                        }
050                } else {
051                        matcher = new RegexpMatcher(args);
052                }
053                return args.isInvertMatch() ? new InvertedMatcher(matcher) : matcher;
054        }
055
056        private LineProcessor getStandardInputProcessor(ExecutionContext context, LineProcessor output, GrepArguments args) {
057                final LineMatcher matcher = getMatcher(args);
058                if (args.isCount()) {
059                        return new CountMatchingLinesProcessor(this, context, output, matcher);
060                } else if (args.isMatchingFiles()) {
061                        return new WriteFilesWithMatchingLinesProcessor(this, context, output, matcher);
062                }
063                return new WriteMatchingLinesProcessor(this, context, output, matcher);
064        }
065        private LineProcessor getFileInputProcessor(List<FileInput> inputs, ExecutionContext context, LineProcessor output, GrepArguments args) {
066                if (args.isCount()) {
067                        final LineMatcher matcher = getMatcher(args);
068                        final InputProcessor processor = new CountMatchingLinesProcessor(this, context, output, matcher);
069                        return new MultipleInputLineProcessor(inputs, processor, output);
070                } else if (args.isMatchingFiles()) {
071                        final LineMatcher matcher = getMatcher(args);
072                        final InputProcessor processor = new WriteFilesWithMatchingLinesProcessor(this, context, output, matcher);
073                        return new MultipleInputLineProcessor(inputs, processor, output);
074                }
075
076                //standard grep output
077                final LineProcessor standardInputProcessor = getStandardInputProcessor(context, output, args);
078                return new RedirectInputLineProcessor(inputs, standardInputProcessor);
079        }
080}