Package org.jnode.shell

Source Code of org.jnode.shell.CommandInfo

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.shell;

import org.jnode.shell.syntax.ArgumentBundle;
import org.jnode.shell.syntax.SyntaxBundle;

/**
* A CommandInfo object is a descriptor used by the CommandShell and CommandInvokers
* to hold information about a command that is being prepared for execution.
*
* There are two basic types of command's that can be described. The first type is
* a JNode command that implements {@link Command} by extending {@link AbstractCommand}.
* The other type is generally refered to as a 'classic Java' command, and refers to
* command that is executed via its {@code main} method. This type of command may have
* an associated bare command definition in its descriptor. If such a descriptor was
* supplied, an instance of this class will contain the {@link org.jnode.shell.syntax.ArgumentBundle}
* for the command.
*
* @author Ewout Prangsma (epr@users.sourceforge.net)
* @author crawley@jnode.org
* @author chris boertien
*/
public class CommandInfo {
   
    private final Class<?> clazz;
    private final String commandName;
    private final SyntaxBundle syntaxBundle;
    private final ArgumentBundle argBundle;
    private final boolean internal;

    private Command instance;
   
    /**
     * Creates a CommandInfo object for a JNode command.
     *
     * @param clazz the designated {@code Class} for executing the command
     * @param commandName the name, or alias, for the command
     * @param syntaxBundle the syntax definition to parse the command line against
     */
    public CommandInfo(Class<?> clazz, String commandName, SyntaxBundle syntaxBundle, boolean internal) {
        this.clazz = clazz;
        this.internal = internal;
        this.commandName = commandName;
        this.syntaxBundle = syntaxBundle;
        this.argBundle = null;
    }
   
    /**
     * Creates a CommandInfo object for a bare command.
     *
     * If the bare command has a defined {@code ArgumentBundle} then
     * it will be used when parsing the command line.
     *
     * @param clazz the designated {@code Class} for executing the command
     * @param commandName the name, or alias, for the command
     * @param syntaxBundle the syntax definition to parse the command line against
     * @param argBundle the optional {@code ArgumentBundle} to parse the command line against
     */
    public CommandInfo(Class<?> clazz, String commandName, SyntaxBundle syntaxBundle, ArgumentBundle argBundle) {
        this.clazz = clazz;
        this.internal = false;
        this.commandName = commandName;
        this.syntaxBundle = syntaxBundle;
        this.argBundle = argBundle;
    }
   
    /**
     * Creates a CommandInfo object for a builtin command.
     *
     * @param clazz the designated {@code Class} for executing the command
     * @param commandName the name, or alias, for the command
     * @param syntaxBundle the syntax definition to parse the command line against
     * @param instance a prebuilt command instance
     */
    CommandInfo(Class<?> clazz, String commandName, SyntaxBundle syntaxBundle,
            ArgumentBundle argBundle, Command instance) {
        this.clazz = clazz;
        this.internal = true;
        this.commandName = commandName;
        this.syntaxBundle = syntaxBundle;
        this.instance = instance;
        this.argBundle = instance.getArgumentBundle();
    }
   
    /**
     * Gets the {@code Class} for the command.
     *
     * @return the {@code Class} for the command
     */
    public final Class<?> getCommandClass() {
        return clazz;
    }
   
    /**
     * Checks whether this command is considered internal or not.
     *
     * @return true if this is an internal command
     * @see org.jnode.shell.alias.AliasManager#isInternal
     */
    public final boolean isInternal() {
        return internal;
    }
   
    /**
     * Retrieves the argument bundle for the command.
     *
     * If this instance was instantiated with an {@link ArgumentBundle}, then
     * that bundle will be returned. If not, and the target class is a type of
     * {@link Command} then the {@code Command}s {@code ArgumentBundle} will
     * be returned. Otherwise this method will return null.
     *
     * @return an {@code ArgumentBundle} for the command, or null if none can be found
     * @see #CommandInfo(Class,String,SyntaxBundle,ArgumentBundle)
     */
    public final ArgumentBundle getArgumentBundle() {
        if (argBundle == null) {
            if (Command.class.isAssignableFrom(clazz)) {
                try {
                    return ((Command) clazz.newInstance()).getArgumentBundle();
                } catch (Exception e) {
                    // fall through
                }
            }
        }
        return argBundle;
    }

    /**
     * Get the Command instance for this CommandInfo, instantiating it if necessary.
     *
     * @return The Command instance to be used for binding argument and executing the command.
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public final Command createCommandInstance() throws InstantiationException, IllegalAccessException {
        if (instance == null) {
            if (Command.class.isAssignableFrom(clazz)) {
                instance = (Command) (clazz.newInstance());
            }
        }
        return instance;
    }

    /**
     * Get the Command instance for this CommandInfo, without instantiating one.
     *
     * @return The Command instance to be used for binding argument and executing
     * the command, or <code>null</code>.
     */
    public Command getCommandInstance() {
        return instance;
    }
   
    /**
     * Gets the name/alias for this command.
     *
     * @return the command's alias
     */
    public String getCommandName() {
        return commandName;
    }
   
    /**
     * Gets the syntax bundle attached when the CommandInfo was created.
     *
     * @return the initial syntax bundle.
     */
    public SyntaxBundle getSyntaxBundle() {
        return syntaxBundle;
    }

   
    /**
     * Perform command line argument parsing in preparation to invoking a command.
     * This locates the command's class and a suitable command line syntax, then
     * parses against the Syntax, binding the command arguments to Argument objects
     * in an ArgumentBundle object obtained from the Command object.
     *
     * If this CommandInfo object was created from a bare command, then the argBundle
     * will have been previously supplied to parse against.
     *
     * @param cmdLine the command line containing the tokens to parse against the argument bundle.
     * @throws ShellException for problems instantiating the command class, or problems parsing
     *         the command arguments.
     */
    public void parseCommandLine(CommandLine cmdLine) throws ShellException {
        try {
            ArgumentBundle bundle = argBundle;
            if (bundle == null) {
                Command cmd = createCommandInstance();
                if (cmd != null) {
                    bundle = cmd.getArgumentBundle();
                }
            }
           
            if (bundle != null) {
                // Do a full parse to bind the command line argument tokens to corresponding
                // command arguments
                bundle.parse(cmdLine, syntaxBundle);
            }
        } catch (InstantiationException ex) {
            throw new ShellInvocationException("Command class cannot be instantiated", ex);
        } catch (IllegalAccessException ex) {
            throw new ShellInvocationException("Command class cannot be instantiated", ex);
        }
    }
}
TOP

Related Classes of org.jnode.shell.CommandInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.