changeset 1012:d13774aae518

Parse options element in plugin.xml Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-February/005908.html
author Omair Majid <omajid@redhat.com>
date Wed, 27 Feb 2013 14:52:27 -0500
parents 412c3e8caf4b
children 2bb2a1d1aa03
files launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParser.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParserTest.java
diffstat 2 files changed, 154 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParser.java	Wed Feb 27 12:27:17 2013 -0500
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParser.java	Wed Feb 27 14:52:27 2013 -0500
@@ -51,6 +51,8 @@
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
 import org.apache.commons.cli.Options;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -88,6 +90,15 @@
  *       &lt;name&gt;hello&lt;/name&gt;
  *       &lt;description&gt;print hello&lt;/description&gt;
  *       &lt;usage&gt;hello&lt;/usage&gt;
+ *       &lt;options&gt;
+ *         &lt;options&gt;
+ *           &lt;long&gt;long&lt;/long&gt;
+ *           &lt;short&gt;l&lt;/short&gt;
+ *           &lt;hasArg&gt;true&lt;/hasArg&gt;
+ *           &lt;required&gt;true&lt;/required&gt;
+ *           &lt;description&gt;some required and long option&lt;/description&gt;
+ *         &lt;/option&gt;
+ *       &lt;/options&gt;
  *       &lt;bundles&gt;
  *         &lt;bundle&gt;hello-world-plugin-0.1-SNAPSHOT.jar&lt;/bundle&gt;
  *       &lt;/bundles&gt;
@@ -219,8 +230,8 @@
                 usage = node.getTextContent().trim();
             } else if (node.getNodeName().equals("description")) {
                 description = node.getTextContent().trim();
-            } else if (node.getNodeName().equals("arguments")) {
-                options = parseArguments(node);
+            } else if (node.getNodeName().equals("options")) {
+                options = parseOptions(node);
             } else if (node.getNodeName().equals("bundles")) {
                 bundles.addAll(parseBundles(pluginName, name, node));
             } else if (node.getNodeName().equals("dependencies")) {
@@ -280,9 +291,67 @@
         return dependencies;
     }
 
-    private Options parseArguments(Node argumentsNode) {
-        // TODO need to identify a way to express arguments
-        return new Options();
+    private Options parseOptions(Node optionsNode) {
+        Options opts = new Options();
+        NodeList nodes = optionsNode.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeName().equals("group")) {
+                OptionGroup group = parseOptionGroup(node);
+                opts.addOptionGroup(group);
+            } else if (node.getNodeName().equals("option")) {
+                Option option = parseOption(node);
+                opts.addOption(option);
+            }
+        }
+
+        return opts;
+    }
+
+    private OptionGroup parseOptionGroup(Node optionGroupNode) {
+        OptionGroup group = new OptionGroup();
+
+        NodeList nodes = optionGroupNode.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeName().equals("option")) {
+                Option option = parseOption(node);
+                group.addOption(option);
+            } else if (node.getNodeName().equals("required")) {
+                group.setRequired(Boolean.valueOf(node.getTextContent().trim()));
+            }
+        }
+
+        return group;
+    }
+
+    private Option parseOption(Node optionNode) {
+        String longName = null;
+        String shortName = null;
+        String description = null;
+        boolean required = false;
+        boolean hasArg = false;
+
+        NodeList nodes = optionNode.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeName().equals("long")) {
+                longName = node.getTextContent().trim();
+            } else if (node.getNodeName().equals("short")) {
+                shortName = node.getTextContent().trim();
+            } else if (node.getNodeName().equals("description")) {
+                description = node.getTextContent().trim();
+            } else if (node.getNodeName().equals("hasArg")) {
+                hasArg = Boolean.valueOf(node.getTextContent().trim());
+            } else if (node.getNodeName().equals("required")) {
+                required = Boolean.valueOf(node.getTextContent().trim());
+            }
+        }
+
+        Option opt = new Option(shortName, longName, hasArg, description);
+        opt.setArgName(longName != null? longName : shortName);
+        opt.setRequired(required);
+        return opt;
     }
 
     private static class ConfigurationParserErrorHandler implements ErrorHandler {
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParserTest.java	Wed Feb 27 12:27:17 2013 -0500
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParserTest.java	Wed Feb 27 14:52:27 2013 -0500
@@ -37,6 +37,9 @@
 package com.redhat.thermostat.launcher.internal;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -45,6 +48,8 @@
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
 import org.apache.commons.cli.Options;
 import org.junit.Test;
 
@@ -180,4 +185,79 @@
         assertEquals(Arrays.asList("foo", "bar  baz", "buzz"), first.getPluginBundles());
         assertEquals(Arrays.asList("thermostat-foo"), first.getDepenedencyBundles());
     }
+
+    @Test
+    public void testOptionParsing() throws UnsupportedEncodingException {
+        String config = "<?xml version=\"1.0\"?>\n" +
+                "<plugin>\n" +
+                "  <commands>\n" +
+                "    <command type='provides'>\n" +
+                "      <name>test</name>\n" +
+                "      <description>just a test</description>\n" +
+                "      <usage>test [ -a | -b ] -l &lt;foo&gt;</usage>\n" +
+                "      <options>\n" +
+                "        <group>\n" +
+                "          <required>true</required>\n" +
+                "          <option>\n" +
+                "            <long>exclusive-a</long>\n" +
+                "            <short>a</short>\n" +
+                "            <hasArg>false</hasArg>\n" +
+                "            <required>false</required>\n" +
+                "            <description>exclusive option a</description>\n" +
+                "          </option>\n" +
+                "          <option>\n" +
+                "            <long>exclusive-b</long>\n" +
+                "            <short>b</short>\n" +
+                "            <hasArg>false</hasArg>\n" +
+                "            <required>false</required>\n" +
+                "            <description>exclusive option b</description>\n" +
+                "          </option>\n" +
+                "        </group>\n" +
+                "        <option>\n" +
+                "          <long>long</long>\n" +
+                "          <short>l</short>\n" +
+                "          <hasArg>true</hasArg>\n" +
+                "          <required>true</required>\n" +
+                "          <description>some required and long option</description>\n" +
+                "        </option>\n" +
+                "      </options>\n" +
+                "    </command>\n" +
+                "  </commands>\n" +
+                "</plugin>";
+
+        PluginConfiguration result = new PluginConfigurationParser()
+                .parse("test", new ByteArrayInputStream(config.getBytes("UTF-8")));
+
+        assertEquals(0, result.getExtendedCommands().size());
+
+        List<NewCommand> newCommands = result.getNewCommands();
+        assertEquals(1, newCommands.size());
+
+        NewCommand command = newCommands.get(0);
+        assertEquals("test", command.getCommandName());
+        assertEquals("just a test", command.getDescription());
+        assertEquals("test [ -a | -b ] -l <foo>", command.getUsage());
+        Options opts = command.getOptions();
+        assertNull(opts.getOption("foobarbaz"));
+
+        Option requiredOption = opts.getOption("l");
+        assertNotNull(requiredOption);
+
+        Option exclusiveOptionA = opts.getOption("a");
+        assertNotNull(exclusiveOptionA);
+        assertEquals("exclusive-a", exclusiveOptionA.getLongOpt());
+        assertFalse(exclusiveOptionA.hasArg());
+        assertFalse(exclusiveOptionA.isRequired());
+        assertEquals("exclusive option a", exclusiveOptionA.getDescription());
+
+        Option exclusiveOptionB = opts.getOption("b");
+        assertNotNull(exclusiveOptionB);
+        assertEquals("exclusive-b", exclusiveOptionB.getLongOpt());
+        assertFalse(exclusiveOptionB.hasArg());
+        assertFalse(exclusiveOptionB.isRequired());
+        assertEquals("exclusive option b", exclusiveOptionB.getDescription());
+
+        OptionGroup group = opts.getOptionGroup(exclusiveOptionA);
+        assertTrue(group.isRequired());
+    }
 }