001package org.unix4j.unix.cd;
002
003import org.unix4j.command.AbstractCommand;
004import org.unix4j.command.Command;
005import org.unix4j.command.JoinedCommand;
006import org.unix4j.context.DerivedExecutionContext;
007import org.unix4j.context.ExecutionContext;
008import org.unix4j.processor.LineProcessor;
009import org.unix4j.unix.Cd;
010import org.unix4j.util.FileUtil;
011
012import java.io.File;
013import java.util.List;
014
015/**
016 * Implementation of the {@link Cd cd} command.
017 */
018class CdCommand extends AbstractCommand<CdArguments> {
019        public CdCommand(CdArguments arguments) {
020                super(Cd.NAME, arguments);
021        }
022
023        @Override
024        public Command<CdArguments> join(Command<?> next) {
025                return join(this, next);
026        }
027
028        private static Command<CdArguments> join(Command<CdArguments> first, Command<?> second) {
029                return new JoinedCommand<CdArguments>(first, second) {
030                        @Override
031                        public LineProcessor execute(ExecutionContext context, LineProcessor output) {
032                                final CdArguments args = getArguments(context);
033                                final File file;
034                                if (args.isPathSet()) {
035                                        final String path = args.getPath(context);
036                                        final List<File> files = FileUtil.expandFiles(context.getCurrentDirectory(), path);
037                                        if (files.isEmpty()) {
038                                                throw new IllegalArgumentException("no file found for path argument: " + path);
039                                        }
040                                        file = files.get(0);
041                                } else if (args.isFileSet()) {
042                                        file = args.getFile();
043                                } else {
044                                        file = context.getUserHome();
045                                }
046                                if (!file.isDirectory()) {
047                                        throw new IllegalArgumentException("not a valid directory: " + file.getAbsolutePath());
048                                }
049                                final DerivedExecutionContext currentDirContext = new DerivedExecutionContext(context);
050                                currentDirContext.setCurrentDirectory(file);
051                                return super.execute(currentDirContext, output);
052                        }
053                        @Override
054                        public Command<?> join(Command<?> next) {
055                                return CdCommand.join(getFirst(), getSecond().join(next));
056                        }
057                };
058        }
059
060        @Override
061        public LineProcessor execute(ExecutionContext context, final LineProcessor output) {
062                return output;// pipe through, we don't do anything with the input or
063                                                // output
064        }
065}