Revision: 5476 http://jnode.svn.sourceforge.net/jnode/?rev=5476&view=rev Author: chrisboertien Date: 2009-05-11 17:39:41 +0000 (Mon, 11 May 2009)
Log Message: ----------- Bare commands implementation This commit contains documetation for the spec parser and related changes to the shell code Signed-off-by: chrisboertien <chris.boert...@gmail.com> Modified Paths: -------------- trunk/shell/src/shell/org/jnode/shell/CommandInfo.java trunk/shell/src/shell/org/jnode/shell/CommandRunner.java trunk/shell/src/shell/org/jnode/shell/CommandShell.java trunk/shell/src/shell/org/jnode/shell/syntax/ArgumentSpecLoader.java Modified: trunk/shell/src/shell/org/jnode/shell/CommandInfo.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/CommandInfo.java 2009-05-11 17:38:32 UTC (rev 5475) +++ trunk/shell/src/shell/org/jnode/shell/CommandInfo.java 2009-05-11 17:39:41 UTC (rev 5476) @@ -27,9 +27,18 @@ /** * 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 (e...@users.sourceforge.net) * @author craw...@jnode.org + * @author chris boertien */ public final class CommandInfo { @@ -40,7 +49,15 @@ 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 + * @param argBundle the optional {...@code ArgumentBundle} to parse the command line against + */ public CommandInfo(Class<?> clazz, String commandName, SyntaxBundle syntaxBundle, boolean internal) { this.clazz = clazz; this.internal = internal; @@ -59,7 +76,7 @@ * @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; @@ -67,15 +84,37 @@ this.syntaxBundle = syntaxBundle; this.argBundle = argBundle; } - + + /** + * Gets the {...@code Class} for the command. + * + * @return the {...@code Class} for the command + */ public final Class<?> getCommandClass() { return clazz; } - + + /** + * Checks wether 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)) { @@ -107,6 +146,7 @@ /** * 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>. */ @@ -114,6 +154,11 @@ return instance; } + /** + * Gets the name/alias for this command. + * + * @return the command's alias + */ public String getCommandName() { return commandName; } Modified: trunk/shell/src/shell/org/jnode/shell/CommandRunner.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/CommandRunner.java 2009-05-11 17:38:32 UTC (rev 5475) +++ trunk/shell/src/shell/org/jnode/shell/CommandRunner.java 2009-05-11 17:39:41 UTC (rev 5476) @@ -109,7 +109,17 @@ stackTrace(ex); } } - + + /** + * Prepare the command for execution. + * + * If the command is not a type of Command then the main method will + * be prepared for invoking with arguments supplied from the command + * line. + * + * This will fail to complete if the command line parsing fails, or if + * the main method for the class could not be found. + */ private void prepare() throws ShellException { Command command; try { @@ -144,7 +154,14 @@ } } } - + + /** + * Executes the command. + * + * For a JNode command, this will initialie and execute the command. For + * other commands the main method will be invoked via reflection with the + * set of arguments supplied on the command line. + */ private void execute() throws Throwable { try { if (method != null) { @@ -199,7 +216,7 @@ ex.printStackTrace(shellErr); } } - + public Method getMethod() { return method; } Modified: trunk/shell/src/shell/org/jnode/shell/CommandShell.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/CommandShell.java 2009-05-11 17:38:32 UTC (rev 5475) +++ trunk/shell/src/shell/org/jnode/shell/CommandShell.java 2009-05-11 17:39:41 UTC (rev 5476) @@ -87,6 +87,7 @@ * @author epr * @author Fabien DUMINY * @author craw...@jnode.org + * @author chris boertien */ public class CommandShell implements Runnable, Shell, ConsoleListener { @@ -661,7 +662,25 @@ throws ShellException { return this.invoker.invokeAsynchronous(cmdLine); } - + + /** + * Gets a {...@link CommandInfo} object representing the given command/alias. + * + * If the given command is a known alias, and the {...@code Class} for the alias + * is a type of {...@link Command} then a {...@code CommandInfo} object for a JNode + * command will be returned. If the {...@code Class} is a non-JNode command and + * a bare command definition for the alias exists, then a {...@code CommandInfo} + * object will be created that contains an {...@link org.jnode.shell.syntax.ArgumentBundle ArgumentBundle} + * will be created. + * + * If the given command is not an alias, then it will be assumed to be a + * class name, and an attempt will be made to load the a {...@code Class} for + * that name, and create a {...@code CommandInfo} object for it. + * + * @param cmd an alias or class name + * @return a {...@code CommandInfo} object representing the given command + * @throws ShellException, if the class could not be found + */ public CommandInfo getCommandInfo(String cmd) throws ShellException { SyntaxBundle syntaxBundle = getSyntaxManager().getSyntaxBundle(cmd); try { Modified: trunk/shell/src/shell/org/jnode/shell/syntax/ArgumentSpecLoader.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/syntax/ArgumentSpecLoader.java 2009-05-11 17:38:32 UTC (rev 5475) +++ trunk/shell/src/shell/org/jnode/shell/syntax/ArgumentSpecLoader.java 2009-05-11 17:39:41 UTC (rev 5476) @@ -25,10 +25,64 @@ import java.util.List; import java.util.Map; +/** + * Loads arguments from a syntax extension point descriptor. + * + * In order to provide the benefits of JNode's parsing, completion and help + * systems, a command requires an {...@link ArgumentBundle} to parse a + * {...@link org.jnode.shell.CommandLine}. Even if that command is not actually + * a {...@link org.jnode.shell.Command}, a description of {...@code Argument}s can + * be defined and used. + * + * Argument bundle descriptions are provided as sibling elements to syntax nodes + * and are defined with {...@code argument-bundle} tags. This tag requires than an {...@code alias} + * attribute be given. {...@code argument-bundle} accepts {...@code argument} tags that provide + * definitions for constructing arguments. It also allows a single {...@code typedefs} node to + * be supplied as the first child. + * + * A {...@code typedefs} block contains {...@code typedef} tags with a mapping between an + * arbitrary string, and a fully qualified class name for an {...@code Argument} using + * the {...@code name} and {...@code value} attributes respectively. Although the {...@code name} + * attribute has no restrictions as to what is used, the generally accepted format, for + * clarity in the descriptor, is the name of the argument class. For example a typedef + * for {...@code org.jnode.shell.syntax.FileArgument} would be: + * + * <typedef name="FileArgument" value="org.jnode.shell.syntax.FileArgument"> + * + * The rest of the child nodes to {...@code argument-bundle} must be {...@code argument} tags. + * {...@code argument} tags require a 'label' and {...@code type} attribute. The 'label' is the + * identified which maps the {...@code Argument} to a node in the syntax. The {...@code type} is + * the fully qualified class name of the {...@code Argument}, or the name of a {...@code typedef}. + * + * An {...@code argument} tag may also contain {...@code param} tags to specify more paramaters for an + * {...@code Argument}s constructor. The {...@code param} tags must be specified in the order + * in which they occur in the constructor. Each {...@code param} tag specified two required + * attributes, a {...@code type} which tells the kind of the paramater, and a value to + * supply the constuctor upon insantiation. The value must be parseable to the + * given type. If an int type is supplied, but the value cannot be parsed as + * an {...@code int} than the parsing will fail. + * + * Currently the only supported types are int, String and flags. + * + * The {...@code flags} type is a special type that fills in an {...@code Argument}'s flags + * paramater with something other than 0 (None). If the defined argument does + * not set any non-default flags, it is recommended that no {...@code param} be supplied + * for clarity in the descriptor. + * + * @see Argument + * @see ArgumentBundle + * @author chris boertien + */ public class ArgumentSpecLoader { private Map<String, String> typeDefs; + /** + * Parses a list of {...@link Argument}s as {...@code ArgumentSpec} objects. + * + * @return an array of {...@code ArgumentSpec}s + * @throws SyntaxFailureException if there was an error in the spec. + */ public ArgumentSpec[] loadArguments(SyntaxSpecAdapter element) { String alias = element.getAttribute("alias"); if (alias == null) { @@ -54,6 +108,10 @@ throw new SyntaxFailureException("No arguments found in 'argument-bundle' node for : " + alias); } + /** + * Parses typedefs used to map a String to a fully qualified class + * name for an argument. + */ private void doTypeDefs(SyntaxSpecAdapter element) { int numTypeDefs = element.getNosChildren(); if (numTypeDefs > 0) { @@ -71,6 +129,9 @@ } } + /** + * Parses an argument. + */ private ArgumentSpec doLoad(SyntaxSpecAdapter element) { if (!element.getName().equals("argument")) { throw new SyntaxFailureException("Not a valid child of 'argument-bundle': " + element.getName()); @@ -113,9 +174,14 @@ } } + /** + * Parses a paramater for the constructor of an argument. + * + * Currently acceptable types: flags, int, String + */ private void parseParam(SyntaxSpecAdapter element, int i, Object[] params, Class<?>[] paramTypes) { if (!element.getName().equals("param")) { - throw new SyntaxFailureException("'arg' contains a child that is not a 'param': " + element.getName()); + throw new SyntaxFailureException("'argument' contains a child that is not a 'param': " + element.getName()); } String type = element.getAttribute("type"); String value = element.getAttribute("value"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your production scanning environment may not be a perfect world - but thanks to Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700 Series Scanner you'll get full speed at 300 dpi even with all image processing features enabled. http://p.sf.net/sfu/kodak-com _______________________________________________ Jnode-svn-commits mailing list Jnode-svn-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jnode-svn-commits