changeset 1686:8b8acefac871

Add boolean add-file-completion to Thermostat-Plugin schema PR2275 Reviewed-by: jerboaa, neugens, omajid Review-Thread: http://icedtea.classpath.org/pipermail/thermostat/2015-March/013203.html
author Lukasz Dracz <ldracz@redhat.com>
date Wed, 25 Mar 2015 11:35:00 -0400
parents c30a5686db0f
children 17fbcd8c00ac
files distribution/docs/thermostat-plugin.xsd launcher/src/main/java/com/redhat/thermostat/launcher/internal/BasicCommandInfo.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/BuiltInCommandInfo.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandInfo.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/CompoundCommandInfoSource.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginConfiguration.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParser.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginInfoSource.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/ShellCommand.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/BasicCommandInfoTest.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/BuiltInCommandInfoTest.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParserTest.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/ShellCommandTest.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/TestCommandInfo.java validate-command/distribution/thermostat-plugin.xml vm-heap-analysis/distribution/thermostat-plugin.xml
diffstat 16 files changed, 171 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/distribution/docs/thermostat-plugin.xsd	Tue Mar 10 16:30:15 2015 +0100
+++ b/distribution/docs/thermostat-plugin.xsd	Wed Mar 25 11:35:00 2015 -0400
@@ -36,6 +36,13 @@
 
 <xs:element name="required" type="xs:boolean"/>
 
+<xs:element name="add-file-completion" type="xs:boolean">
+  <xs:annotation>
+    <xs:documentation>Determines whether a command gets tab completion added for files.
+      That is, in addition to command option completion.</xs:documentation>
+  </xs:annotation>
+</xs:element>
+
 <xs:element name="id" type="xs:string"/>
 
 <xs:element name="configuration" type="xs:string"/>
@@ -97,6 +104,7 @@
       <xs:element ref="options" minOccurs="0" maxOccurs="1"/>
       <xs:element ref="environments"/>
       <xs:element ref="bundles"/>
+      <xs:element ref="add-file-completion" minOccurs="0" maxOccurs="1"/>
     </xs:sequence>
   </xs:complexType>
 </xs:element> 
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BasicCommandInfo.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BasicCommandInfo.java	Wed Mar 25 11:35:00 2015 -0400
@@ -36,7 +36,6 @@
 
 package com.redhat.thermostat.launcher.internal;
 
-import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -53,8 +52,9 @@
     private final Options options;
     private final Set<Environment> environments;
     private final List<BundleInformation> bundles;
+    private final boolean fileTabCompletionNeeded;
 
-    public BasicCommandInfo(String name, String summary, String description, String usage, Options options, Set<Environment> environments, List<BundleInformation> bundles) {
+    public BasicCommandInfo(String name, String summary, String description, String usage, Options options, Set<Environment> environments, List<BundleInformation> bundles, boolean fileTabCompletionNeeded) {
         this.name = name;
         this.summary = summary;
         this.description = description;
@@ -62,6 +62,7 @@
         this.options = options;
         this.environments = environments;
         this.bundles = bundles;
+        this.fileTabCompletionNeeded = fileTabCompletionNeeded;
     }
 
     @Override
@@ -90,6 +91,11 @@
     }
 
     @Override
+    public boolean needsFileTabCompletions() {
+        return fileTabCompletionNeeded;
+    }
+
+    @Override
     public Set<Environment> getEnvironments() {
         return environments;
     }
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BuiltInCommandInfo.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BuiltInCommandInfo.java	Wed Mar 25 11:35:00 2015 -0400
@@ -39,7 +39,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Map.Entry;
@@ -64,6 +63,7 @@
     private static final String PROPERTY_USAGE = "usage";
     private static final String PROPERTY_OPTIONS = "options";
     private static final String PROPERTY_ENVIRONMENTS = "environments";
+    private static final String PROPERTY_FILE_COMPLETION = "add-file-completion";
 
     private static final String PROP_SHORTOPT = ".short";
     private static final String PROP_LONGOPT = ".long";
@@ -75,6 +75,7 @@
     private Options options;
     private EnumSet<Environment> environment;
     private List<BundleInformation> dependencies;
+    private boolean fileTabCompletionNeeded;
 
     BuiltInCommandInfo(String commandName, Properties properties) {
         options = new Options();
@@ -93,6 +94,8 @@
                 learnOptions((String) entry.getValue(), properties);
             } else if (key.equals(PROPERTY_ENVIRONMENTS)) {
                 environment = parseEnvironment(properties.getProperty(key));
+            } else if (key.equals(PROPERTY_FILE_COMPLETION)) {
+                fileTabCompletionNeeded = Boolean.parseBoolean(properties.getProperty(key));
             }
         }
     }
@@ -396,5 +399,10 @@
     public List<BundleInformation> getBundles() {
         return dependencies;
     }
+
+    @Override
+    public boolean needsFileTabCompletions() {
+        return fileTabCompletionNeeded;
+    }
 }
 
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandInfo.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandInfo.java	Wed Mar 25 11:35:00 2015 -0400
@@ -80,6 +80,11 @@
      */
     public Options getOptions();
 
+    /**
+     * Returns whether the command will get tab completions for files
+     */
+    public boolean needsFileTabCompletions();
+
     List<BundleInformation> getBundles();
 
 }
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CompoundCommandInfoSource.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CompoundCommandInfoSource.java	Wed Mar 25 11:35:00 2015 -0400
@@ -138,9 +138,10 @@
         List<BundleInformation> bundles = new ArrayList<>();
         bundles.addAll(info1.getBundles());
         bundles.addAll(info2.getBundles());
+        boolean fileTabCompletionNeeded = info1.needsFileTabCompletions() || info2.needsFileTabCompletions();
 
 
-        return new BasicCommandInfo(name, summary, description, usage, options, environment, bundles);
+        return new BasicCommandInfo(name, summary, description, usage, options, environment, bundles, fileTabCompletionNeeded);
     }
 
     private <T> T selectBest(T first, T second) {
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginConfiguration.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginConfiguration.java	Wed Mar 25 11:35:00 2015 -0400
@@ -120,11 +120,13 @@
         private final Options options;
         private final Set<Environment> environment;
         private final List<BundleInformation> bundles;
+        private final boolean fileTabCompletionNeeded;
 
         public NewCommand(String name, String usage, String summary, String description,
                 List<String> positionalArguments, Options options,
                 Set<Environment> environment,
-                List<BundleInformation> bundles) {
+                List<BundleInformation> bundles,
+                boolean fileTabCompletionNeeded) {
             this.commandName = name;
             this.usage = usage;
             this.summary = summary;
@@ -133,6 +135,7 @@
             this.options = options;
             this.environment = environment;
             this.bundles = bundles;
+            this.fileTabCompletionNeeded = fileTabCompletionNeeded;
         }
 
         public String getCommandName() {
@@ -175,6 +178,9 @@
             return Collections.unmodifiableList(bundles);
         }
 
+        public boolean needsFileTabCompletions() {
+            return fileTabCompletionNeeded;
+        }
     }
 
     public static class PluginID {
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParser.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParser.java	Wed Mar 25 11:35:00 2015 -0400
@@ -359,6 +359,7 @@
         Options options = new Options();
         Set<Environment> availableInEnvironments = EnumSet.noneOf(Environment.class);
         List<BundleInformation> bundles = new ArrayList<>();
+        boolean fileTabCompletionNeeded = false;
 
         NodeList nodes = commandNode.getChildNodes();
         for (int i = 0; i < nodes.getLength(); i++) {
@@ -379,6 +380,8 @@
                 availableInEnvironments = parseEnvironment(pluginName, name, node);
             } else if (node.getNodeName().equals("bundles")) {
                 bundles.addAll(parseBundles(pluginName, name, node));
+            } else if (node.getNodeName().equals("add-file-completion")) {
+                fileTabCompletionNeeded = Boolean.parseBoolean(node.getTextContent().trim());
             }
         }
 
@@ -397,7 +400,7 @@
                     "name='" + name + "', description='" + description + "', options='" + options + "'");
             return null;
         } else {
-            return new NewCommand(name, usage, summary, description, arguments, options, availableInEnvironments, bundles);
+            return new NewCommand(name, usage, summary, description, arguments, options, availableInEnvironments, bundles, fileTabCompletionNeeded);
         }
     }
 
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginInfoSource.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/PluginInfoSource.java	Wed Mar 25 11:35:00 2015 -0400
@@ -178,7 +178,8 @@
                     usage,
                     command.getOptions(),
                     command.getEnvironments(),
-                    command.getBundles());
+                    command.getBundles(),
+                    command.needsFileTabCompletions());
 
             allNewCommands.put(commandName, info);
         }
@@ -200,7 +201,8 @@
                         old.getUsage(),
                         old.getOptions(),
                         old.getEnvironments(),
-                        updatedBundles);
+                        updatedBundles,
+                        old.needsFileTabCompletions());
                 allNewCommands.put(entry.getKey(), updated);
                 iter.remove();
             }
@@ -230,7 +232,7 @@
     }
 
     private BasicCommandInfo createCommandInfo(String name, List<BundleInformation> bundles) {
-        return new BasicCommandInfo(name, null, null, null, null, null, bundles);
+        return new BasicCommandInfo(name, null, null, null, null, null, bundles, false);
     }
 
     public Map<String, String> getConfiguration(String pluginID, String fileName) throws IOException {
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/ShellCommand.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/ShellCommand.java	Wed Mar 25 11:35:00 2015 -0400
@@ -243,7 +243,7 @@
                     }
                 }
 
-                if (info.getName().equals("validate") || info.getName().equals("save-heap-dump-to-file")) {
+                if (info.needsFileTabCompletions()) {
                     AggregateCompleter optionsAndFiles = new AggregateCompleter(new StringsCompleter(options), new FileNameCompleter());
                     commands.add(optionsAndFiles);
                 } else {
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BasicCommandInfoTest.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BasicCommandInfoTest.java	Wed Mar 25 11:35:00 2015 -0400
@@ -59,8 +59,9 @@
         final Options OPTIONS = new Options();
         final Set<Environment> ENVIRONMENT = EnumSet.noneOf(Environment.class);
         final List<BundleInformation> BUNDLES = Collections.emptyList();
+        final boolean ADD_FILE_COMPLETION = true;
 
-        BasicCommandInfo info = new BasicCommandInfo(NAME, SUMMARY, DESCRIPTION, USAGE, OPTIONS, ENVIRONMENT, BUNDLES);
+        BasicCommandInfo info = new BasicCommandInfo(NAME, SUMMARY, DESCRIPTION, USAGE, OPTIONS, ENVIRONMENT, BUNDLES, ADD_FILE_COMPLETION);
 
         assertEquals(NAME, info.getName());
         assertEquals(SUMMARY, info.getSummary());
@@ -68,6 +69,7 @@
         assertEquals(USAGE, info.getUsage());
         assertEquals(OPTIONS, info.getOptions());
         assertEquals(BUNDLES, info.getBundles());
+        assertEquals(ADD_FILE_COMPLETION, info.needsFileTabCompletions());
 
         assertEquals(String.format("%s (summary='%s', description='%s', dependencies='%s')", NAME, SUMMARY, DESCRIPTION, BUNDLES.toString()),
                 info.toString());
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BuiltInCommandInfoTest.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BuiltInCommandInfoTest.java	Wed Mar 25 11:35:00 2015 -0400
@@ -311,5 +311,16 @@
         assertTrue(commandEnv.contains(Environment.CLI));
         assertTrue(commandEnv.contains(Environment.SHELL));
     }
+
+    @Test
+    public void verifyFileUsage() {
+        Properties props = new Properties();
+        String name = "name";
+        String usage = "true";
+        props.put("add-file-completion", usage);
+        BuiltInCommandInfo info = new BuiltInCommandInfo(name, props);
+
+        assertTrue(info.needsFileTabCompletions());
+    }
 }
 
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParserTest.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParserTest.java	Wed Mar 25 11:35:00 2015 -0400
@@ -595,5 +595,98 @@
         assertNull(dbUrlOption);
     }
 
+    @Test
+    public void testUsesFileWithTrueEntry() throws UnsupportedEncodingException {
+        String config = "<?xml version=\"1.0\"?>\n" +
+                "<plugin>\n" +
+                "  <commands>\n" +
+                "    <command type='provides'>\n" +
+                "      <name>test</name>\n" +
+                "      <summary>some summary</summary>\n" +
+                "      <description>some description</description>\n" +
+                "      <environments>" +
+                "        <environment>shell</environment>" +
+                "        <environment>cli</environment>" +
+                "      </environments>" +
+                "      <add-file-completion>true</add-file-completion>" +
+                "    </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());
+        assertTrue(command.needsFileTabCompletions());
+    }
+
+    @Test
+    public void testUsesFileWithFalseEntry() throws UnsupportedEncodingException {
+        String config = "<?xml version=\"1.0\"?>\n" +
+                "<plugin>\n" +
+                "  <commands>\n" +
+                "    <command type='provides'>\n" +
+                "      <name>test</name>\n" +
+                "      <summary>some summary</summary>\n" +
+                "      <description>some description</description>\n" +
+                "      <environments>" +
+                "        <environment>shell</environment>" +
+                "        <environment>cli</environment>" +
+                "      </environments>" +
+                "      <add-file-completion>false</add-file-completion>" +
+                "    </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());
+        assertFalse(command.needsFileTabCompletions());
+    }
+
+    @Test
+    public void testUsesFileWithInvalidEntry() throws UnsupportedEncodingException {
+        String config = "<?xml version=\"1.0\"?>\n" +
+                "<plugin>\n" +
+                "  <commands>\n" +
+                "    <command type='provides'>\n" +
+                "      <name>test</name>\n" +
+                "      <summary>some summary</summary>\n" +
+                "      <description>some description</description>\n" +
+                "      <environments>" +
+                "        <environment>shell</environment>" +
+                "        <environment>cli</environment>" +
+                "      </environments>" +
+                "      <add-file-completion>invalid</add-file-completion>" +
+                "    </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());
+        assertFalse(command.needsFileTabCompletions());
+    }
+
 }
 
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/ShellCommandTest.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/ShellCommandTest.java	Wed Mar 25 11:35:00 2015 -0400
@@ -732,6 +732,7 @@
         when(info1.getName()).thenReturn("test1");
         when(info1.getDescription()).thenReturn("test command 1");
         when(info1.getEnvironments()).thenReturn(EnumSet.of(Environment.CLI, Environment.SHELL));
+        when(info1.needsFileTabCompletions()).thenReturn(false);
 
         ArrayList<Option> optionsList1 = new ArrayList<>();
         Option option1 = mock(Option.class);
@@ -758,6 +759,7 @@
         when(info2.getName()).thenReturn("test2longname");
         when(info2.getDescription()).thenReturn("test command 2");
         when(info2.getEnvironments()).thenReturn(EnumSet.of(Environment.CLI, Environment.SHELL));
+        when(info2.needsFileTabCompletions()).thenReturn(false);
 
         ArrayList<Option> optionsList2 = new ArrayList<>();
         Option option4 = mock(Option.class);
@@ -784,6 +786,7 @@
         when(info3.getName()).thenReturn("validate");
         when(info3.getDescription()).thenReturn("mock validate command");
         when(info3.getEnvironments()).thenReturn(EnumSet.of(Environment.CLI, Environment.SHELL));
+        when(info3.needsFileTabCompletions()).thenReturn(true);
 
         ArrayList<Option> optionsList3 = new ArrayList<>();
         Option option7 = mock(Option.class);
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/TestCommandInfo.java	Tue Mar 10 16:30:15 2015 +0100
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/TestCommandInfo.java	Wed Mar 25 11:35:00 2015 -0400
@@ -54,6 +54,7 @@
 
     private Options options = new Options();
     private Set<Environment> environments;
+    private boolean fileTabCompletionNeeded;
 
     public TestCommandInfo(String name) {
         this.name = name;
@@ -96,6 +97,15 @@
         return options;
     }
 
+    @Override
+    public boolean needsFileTabCompletions() {
+        return fileTabCompletionNeeded;
+    }
+
+    public void setFileTabCompletionNeeded(boolean fileTabCompletionNeeded) {
+        this.fileTabCompletionNeeded = fileTabCompletionNeeded;
+    }
+
     public void addOptions(Option... options) {
         for (Option option : options) {
             this.options.addOption(option);
--- a/validate-command/distribution/thermostat-plugin.xml	Tue Mar 10 16:30:15 2015 +0100
+++ b/validate-command/distribution/thermostat-plugin.xml	Wed Mar 25 11:35:00 2015 -0400
@@ -57,6 +57,7 @@
         <bundle><symbolic-name>com.redhat.thermostat.configuration</symbolic-name><version>${project.version}</version></bundle>
         <bundle><symbolic-name>com.redhat.thermostat.plugin.validator</symbolic-name><version>${project.version}</version></bundle>
       </bundles>
+      <add-file-completion>true</add-file-completion>
     </command>
   </commands>
 </plugin>
--- a/vm-heap-analysis/distribution/thermostat-plugin.xml	Tue Mar 10 16:30:15 2015 +0100
+++ b/vm-heap-analysis/distribution/thermostat-plugin.xml	Wed Mar 25 11:35:00 2015 -0400
@@ -372,6 +372,7 @@
         <bundle><symbolic-name>${lucene-core.bundle.symbolic-name}</symbolic-name><version>${lucene.osgi-version}</version></bundle>
         <bundle><symbolic-name>${lucene-analysis.bundle.symbolic-name}</symbolic-name><version>${lucene.osgi-version}</version></bundle>
       </bundles>
+      <add-file-completion>true</add-file-completion>
     </command>
     <command>
       <name>show-heap-histogram</name>