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:
+ * 
+ * &lt;typedef name="FileArgument" 
value="org.jnode.shell.syntax.FileArgument"&gt;
+ *
+ * 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

Reply via email to