changeset 1147:52736b6a71d2

Options tag in schema as optional Reviewed-by: neugens, jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-June/007134.html
author Giovanni Astarita <gastarit@redhat.com>
date Fri, 21 Jun 2013 16:36:21 +0200
parents d3a24826cf5d
children e597d72c3ecb
files distribution/docs/thermostat-plugin.xsd launcher/src/main/java/com/redhat/thermostat/launcher/CommandLineArgumentParseException.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentParseException.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentsParser.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentsParserTest.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java
diffstat 7 files changed, 125 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/distribution/docs/thermostat-plugin.xsd	Mon Jun 24 21:24:21 2013 +0200
+++ b/distribution/docs/thermostat-plugin.xsd	Fri Jun 21 16:36:21 2013 +0200
@@ -53,7 +53,13 @@
     <xs:sequence>
       <xs:element ref="name"/>
       <xs:element ref="bundles"/>
-      <xs:element ref="dependencies" minOccurs="0" maxOccurs="1"/>
+      <xs:element ref="dependencies" minOccurs="0" maxOccurs="1">
+      <xs:annotation>
+        <xs:documentation>
+          Dependencies: depend on other libraries.
+        </xs:documentation>
+      </xs:annotation>
+      </xs:element>
     </xs:sequence>
   </xs:complexType>
 </xs:element>
@@ -66,10 +72,16 @@
       <xs:element ref="usage" minOccurs="0" maxOccurs="1"/>
       <xs:element ref="description"/>
       <xs:element ref="arguments" minOccurs="0" maxOccurs="1"/>
-      <xs:element ref="options"/>
+      <xs:element ref="options" minOccurs="0" maxOccurs="1"/>
       <xs:element ref="environments"/>
       <xs:element ref="bundles"/>
-      <xs:element ref="dependencies"/>
+      <xs:element ref="dependencies">
+      <xs:annotation>
+        <xs:documentation>
+          Dependencies: depend on other commands.
+        </xs:documentation>
+      </xs:annotation>
+      </xs:element>
     </xs:sequence>
   </xs:complexType>
 </xs:element> 
@@ -77,6 +89,11 @@
 
 <xs:element name="arguments">
   <xs:complexType>
+    <xs:annotation>
+      <xs:documentation>
+        "Arguments" tag has been set as optional for commands that don't need any specified argument 
+      </xs:documentation>
+    </xs:annotation>
     <xs:sequence>
       <xs:element ref="argument" minOccurs="0" maxOccurs="1"/>
     </xs:sequence>
@@ -85,6 +102,11 @@
 
 <xs:element name="options">
   <xs:complexType>
+    <xs:annotation>
+      <xs:documentation>
+        "Options" tag has been set as optional for commands that don't need any specified option 
+      </xs:documentation>
+    </xs:annotation>
     <xs:sequence>
       <xs:element ref="group" minOccurs="0" maxOccurs="1"/>
       <xs:element ref="option" minOccurs="1" maxOccurs="unbounded"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/CommandLineArgumentParseException.java	Fri Jun 21 16:36:21 2013 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.launcher;
+
+import com.redhat.thermostat.common.cli.CommandException;
+import com.redhat.thermostat.shared.locale.LocalizedString;
+
+public class CommandLineArgumentParseException extends CommandException {
+
+    public CommandLineArgumentParseException(LocalizedString message) {
+        super(message);
+    }
+
+    public CommandLineArgumentParseException(LocalizedString message, Throwable cause) {
+        super(message, cause);
+    }
+
+
+}
+
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentParseException.java	Mon Jun 24 21:24:21 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright 2012, 2013 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.launcher.internal;
-
-import com.redhat.thermostat.common.cli.CommandException;
-import com.redhat.thermostat.shared.locale.LocalizedString;
-
-public class CommandLineArgumentParseException extends CommandException {
-
-    public CommandLineArgumentParseException(LocalizedString message) {
-        super(message);
-    }
-
-    public CommandLineArgumentParseException(LocalizedString message, Throwable cause) {
-        super(message, cause);
-    }
-
-
-}
-
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentsParser.java	Mon Jun 24 21:24:21 2013 +0200
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentsParser.java	Fri Jun 21 16:36:21 2013 +0200
@@ -43,12 +43,14 @@
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.MissingArgumentException;
 import org.apache.commons.cli.MissingOptionException;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 
 import com.redhat.thermostat.common.cli.Arguments;
+import com.redhat.thermostat.launcher.CommandLineArgumentParseException;
 import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.shared.locale.Translate;
 
@@ -71,17 +73,17 @@
             CommandLine commandLine;
             commandLine = parser.parse(options, args);
             return new CommandLineArguments(commandLine);
-        } catch (MissingOptionException mae) {
-            LocalizedString msg = createMissingOptionsMessage(mae);
-            throw new CommandLineArgumentParseException(msg, mae);
+        } catch (MissingOptionException moe) {
+            LocalizedString msg = createMissingOptionsMessage(moe);
+            throw new CommandLineArgumentParseException(msg, moe);
         } catch (ParseException e) {
             throw new CommandLineArgumentParseException(tr.localize(LocaleResources.PARSE_EXCEPTION_MESSAGE, e.getMessage()), e);
         }
     }
 
-    private LocalizedString createMissingOptionsMessage(MissingOptionException mae) {
+    private LocalizedString createMissingOptionsMessage(MissingOptionException moe) {
         @SuppressWarnings("unchecked")
-        List<String> missingOptions = mae.getMissingOptions();
+        List<String> missingOptions = moe.getMissingOptions();
         String[] presentableMissingOptions = new String[missingOptions.size()];
         int optIndex = 0;
         for (Iterator<String> i = missingOptions.iterator(); i.hasNext();) {
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java	Mon Jun 24 21:24:21 2013 +0200
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java	Fri Jun 21 16:36:21 2013 +0200
@@ -67,6 +67,7 @@
 import com.redhat.thermostat.common.tools.StorageAuthInfoGetter;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.launcher.BundleManager;
+import com.redhat.thermostat.launcher.CommandLineArgumentParseException;
 import com.redhat.thermostat.launcher.internal.CommandInfo.Environment;
 import com.redhat.thermostat.shared.config.InvalidConfigurationException;
 import com.redhat.thermostat.shared.locale.LocalizedString;
@@ -267,14 +268,14 @@
         Arguments args = null;
         try {
             args = parseCommandArguments(cmdArgs, options);
+            setupLogLevel(args);
+            CommandContext ctx = setupCommandContext(cmd, args);
+            cmd.run(ctx);
         } catch (CommandLineArgumentParseException e) {
             out.println(e.getMessage());
             runHelpCommandFor(cmdName);
             return;
         }
-        setupLogLevel(args);
-        CommandContext ctx = setupCommandContext(cmd, args);
-        cmd.run(ctx);
     }
 
     private void outputBadShellContext(boolean inShell, PrintStream out, String cmd) {
@@ -305,7 +306,6 @@
 
     private Arguments parseCommandArguments(String[] cmdArgs, Options options)
             throws CommandLineArgumentParseException {
-
         CommandLineArgumentsParser cliArgsParser = new CommandLineArgumentsParser();
         cliArgsParser.addOptions(options);
         Arguments args = cliArgsParser.parse(cmdArgs);
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentsParserTest.java	Mon Jun 24 21:24:21 2013 +0200
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentsParserTest.java	Fri Jun 21 16:36:21 2013 +0200
@@ -48,6 +48,7 @@
 import org.junit.Test;
 
 import com.redhat.thermostat.common.cli.Arguments;
+import com.redhat.thermostat.launcher.CommandLineArgumentParseException;
 
 public class CommandLineArgumentsParserTest {
 
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java	Mon Jun 24 21:24:21 2013 +0200
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java	Fri Jun 21 16:36:21 2013 +0200
@@ -67,6 +67,7 @@
 import com.redhat.thermostat.common.ActionNotifier;
 import com.redhat.thermostat.common.ApplicationService;
 import com.redhat.thermostat.common.ExitStatus;
+import com.redhat.thermostat.common.Pair;
 import com.redhat.thermostat.common.Version;
 import com.redhat.thermostat.common.cli.AbstractStateNotifyingCommand;
 import com.redhat.thermostat.common.cli.Arguments;
@@ -79,8 +80,6 @@
 import com.redhat.thermostat.launcher.BundleManager;
 import com.redhat.thermostat.launcher.internal.CommandInfo.Environment;
 import com.redhat.thermostat.launcher.internal.DisallowSystemExitSecurityManager.ExitException;
-import com.redhat.thermostat.launcher.internal.HelpCommand;
-import com.redhat.thermostat.launcher.internal.LauncherImpl;
 import com.redhat.thermostat.launcher.internal.LauncherImpl.LoggingInitializer;
 import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.DbService;
@@ -97,6 +96,7 @@
     private static final String name1 = "test1";
     private static final String name2 = "test2";
     private static final String name3 = "test3";
+    private static final String name4 = "test4";
     private static SecurityManager secMan;
       
     @BeforeClass
@@ -182,7 +182,6 @@
         when(info2.getOptions()).thenReturn(options2);
         when(info2.getEnvironments()).thenReturn(EnumSet.of(Environment.SHELL, Environment.CLI));
 
-
         TestCommand cmd3 = new TestCommand();
         CommandInfo info3 = mock(CommandInfo.class);
         when(info3.getName()).thenReturn(name3);
@@ -191,6 +190,16 @@
         when(info3.getOptions()).thenReturn(new Options());
         when(info3.getEnvironments()).thenReturn(EnumSet.of(Environment.SHELL, Environment.CLI));
 
+        // This TestCommand object doesn't need to connect to storage,
+        // and it is used to test commands without any required option
+        TestCommand cmd4 = new TestCommand();
+        CommandInfo info4 = mock(CommandInfo.class);
+        when(info4.getName()).thenReturn(name4);
+        cmd4.setStorageRequired(false);
+        when(info4.getDescription()).thenReturn("description 4");
+        when(info4.getOptions()).thenReturn(new Options());
+        when(info4.getEnvironments()).thenReturn(EnumSet.of(Environment.SHELL, Environment.CLI));
+        
         AbstractStateNotifyingCommand basicCmd = mock(AbstractStateNotifyingCommand.class);
         CommandInfo basicInfo = mock(CommandInfo.class);
         when(basicInfo.getName()).thenReturn("basic");
@@ -210,7 +219,6 @@
         when(helpCommandInfo.getUsage()).thenReturn("thermostat help");
         when(helpCommandInfo.getEnvironments()).thenReturn(EnumSet.of(Environment.SHELL, Environment.CLI));
 
-
         HelpCommand helpCommand = new HelpCommand();
 
         CommandRegistry reg = ctxFactory.getCommandRegistry();
@@ -218,6 +226,7 @@
         reg.registerCommand(name1, cmd1);
         reg.registerCommand(name2, cmd2);
         reg.registerCommand(name3, cmd3);
+        reg.registerCommand(name4, cmd4);
         reg.registerCommand("basic", basicCmd);
 
         infos = mock(CommandInfoSource.class);
@@ -225,6 +234,7 @@
         when(infos.getCommandInfo(name1)).thenReturn(info1);
         when(infos.getCommandInfo(name2)).thenReturn(info2);
         when(infos.getCommandInfo(name3)).thenReturn(info3);
+        when(infos.getCommandInfo(name4)).thenReturn(info4);
         when(infos.getCommandInfo("basic")).thenReturn(basicInfo);
         when(infos.getCommandInfo("help")).thenReturn(helpCommandInfo);
 
@@ -234,6 +244,8 @@
         infoList.add(info1);
         infoList.add(info2);
         infoList.add(info3);
+        infoList.add(info4);
+        
         when(infos.getCommandInfos()).thenReturn(infoList);
 
         helpCommand.setCommandInfoSource(infos);
@@ -280,7 +292,8 @@
                         + " basic         nothing that means anything\n"
                         + " test1         description 1\n"
                         + " test2         description 2\n"
-                        + " test3         description 3\n";
+                        + " test3         description 3\n"
+                        + " test4         description 4\n";
         runAndVerifyCommand(new String[0], expected, false);
     }
 
@@ -301,7 +314,8 @@
             + " basic         nothing that means anything\n"
             + " test1         description 1\n"
             + " test2         description 2\n"
-            + " test3         description 3\n";
+            + " test3         description 3\n"
+            + " test4         description 4\n";
         runAndVerifyCommand(new String[] {"--help"}, expected, false);
     }
 
@@ -315,7 +329,8 @@
             + " basic         nothing that means anything\n"
             + " test1         description 1\n"
             + " test2         description 2\n"
-            + " test3         description 3\n";
+            + " test3         description 3\n"
+            + " test4         description 4\n";
         runAndVerifyCommand(new String[] {"-help"}, expected, false);
     }
 
@@ -329,7 +344,8 @@
             + " basic         nothing that means anything\n"
             + " test1         description 1\n"
             + " test2         description 2\n"
-            + " test3         description 3\n";
+            + " test3         description 3\n"
+            + " test4         description 4\n";
         runAndVerifyCommand(new String[] {"foobarbaz"}, expected, false);
     }
 
@@ -343,7 +359,8 @@
             + " basic         nothing that means anything\n"
             + " test1         description 1\n"
             + " test2         description 2\n"
-            + " test3         description 3\n";
+            + " test3         description 3\n"
+            + " test4         description 4\n";
         runAndVerifyCommand(new String[] {"foo",  "--bar", "baz"}, expected, false);
     }
 
@@ -370,6 +387,12 @@
                 + "  -l,--logLevel <arg>\n";
         runAndVerifyCommand(new String[] {"test1"}, expected, false);
     }
+    
+    @Test
+    public void testMissingNotRequiredOption() {
+        String expected = "";
+        runAndVerifyCommand(new String[] {"test4"}, expected, false);
+    }
 
     @Test
     public void testOptionMissingRequiredArgument() {
@@ -393,7 +416,8 @@
                 + " basic         nothing that means anything\n"
                 + " test1         description 1\n"
                 + " test2         description 2\n"
-                + " test3         description 3\n";
+                + " test3         description 3\n"
+                + " test4         description 4\n";
             runAndVerifyCommand(new String[] {"foo"}, expected, false);
     }