001package org.unix4j.command;
002
003import org.unix4j.context.ExecutionContext;
004import org.unix4j.processor.LineProcessor;
005import org.unix4j.variable.VariableContext;
006
007/**
008 * A command is an executable unit defined by the command {@link #getName()
009 * name} and the command line {@link #getArguments(ExecutionContext) arguments}.
010 * To execute a command, {@link #execute(ExecutionContext, LineProcessor)} is
011 * called which returns a {@link LineProcessor} object to perform the
012 * line-by-line command execution.
013 * <p>
014 * Commands can be {@link #join(Command) joined} to other commands which usually
015 * means that the first command's output forms the input of the second command.
016 * 
017 * @param <A>
018 *            the type parameter defining the arguments and options of the
019 *            command
020 */
021public interface Command<A extends Arguments<A>> {
022        /**
023         * Returns the name of this command, usually a lower-case string such as
024         * "grep" or "ls".
025         * 
026         * @return the command name, usually a lower case string
027         */
028        String getName();
029
030        /**
031         * Returns the implementation specific command arguments and options for the
032         * given execution context. Note that the returned arguments instance may
033         * contain unresolved variables if variables have been passed to the
034         * command creation method. Variables can are resolved if they are defined
035         * in the {@link VariableContext} returned by the given {@code context} 
036         * object. No variables are resolved if {@code context} is null. 
037         * 
038         * @param context
039         *            the execution context with access to variables and value 
040         *            converters, or null if no variables should be resolved
041         * @return the arguments and options for this command
042         * @see Arguments#getForContext(ExecutionContext)
043         */
044        A getArguments(ExecutionContext context);
045
046        /**
047         * Returns a new command representing the combination of {@code this}
048         * command with {@code next}. The returned command executes {@code this}
049         * command first and usually joins the output to the {@code next} command's
050         * input.
051         * <p>
052         * Note that some commands may use a slightly different interpretation of
053         * "joining a command". The {@code xargs} command for instance uses its
054         * joined command as target command; the values collected by {@code xargs}
055         * on its input stream are passed to the target command as arguments instead
056         * of as input.
057         * 
058         * @param next
059         *            the next command to join to this command
060         * @return a new command representing the combination of {@code this}
061         *         command joined to {@code next}
062         */
063        Command<?> join(Command<?> next);
064
065        /**
066         * Executes this command and returns a {@link LineProcessor} object. Calling
067         * this method initiates the command execution, but the real processing of
068         * the command takes place when lines are passed to the returned
069         * {@code LineProcessor} object. The command execution is terminated by
070         * calling {@link LineProcessor#finish()}.
071         * <p>
072         * The command writes its output to the specified {@code output} object.
073         * Depending on the command implementation, the output is written when lines
074         * are passed to the {@code LineProcessor} returned by this method, or when
075         * the execution terminates with the {@code finish()} call.
076         * 
077         * @param context
078         *            context object providing access to the current directory,
079         *            environment variables and other information useful for the
080         *            command during its execution
081         * @param output
082         *            the output to write to
083         * @return true if another invocation with more input is expected, and false
084         *         if this command has completed and no other invocation is
085         *         required.
086         */
087        LineProcessor execute(ExecutionContext context, LineProcessor output);
088
089        /**
090         * Returns a string representation of the command instance including the
091         * argument and option values defined for the command.
092         * 
093         * @return a string representation of the command including arguments and
094         *         options, such as "grep -matchString myString -ignoreCase"
095         */
096        @Override
097        String toString();
098}