Martin Peřina has uploaded a new change for review.

Change subject: core: Adds cli parsers with POSIX and GNU long args
......................................................................

core: Adds cli parsers with POSIX and GNU long args

Adds command line arguments parser that supports parsing POSIX and GNU
long arguments.

Change-Id: If0dd854826433b577b902eaba6b4fcd8967d1199
Bug-Url: https://bugzilla.redhat.com/904029
Signed-off-by: Martin Perina <mper...@redhat.com>
---
A 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/cli/ExtendedCliParser.java
A 
backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/cli/ExtendedCliParserTest.java
2 files changed, 332 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/28/19128/1

diff --git 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/cli/ExtendedCliParser.java
 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/cli/ExtendedCliParser.java
new file mode 100644
index 0000000..c89dff1
--- /dev/null
+++ 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/cli/ExtendedCliParser.java
@@ -0,0 +1,157 @@
+package org.ovirt.engine.core.utils.cli;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Implements argument parser, that supports parsing POSIX and GNU long 
arguments
+ */
+public class ExtendedCliParser {
+    /**
+     * POSIX argument prefix
+     */
+    private static final String PREFIX_POSIX = "-";
+
+    /**
+     * GNU long argument prefix
+     */
+    private static final String PREFIX_GNU_LONG = "--";
+
+    /**
+     * POSIX argument value separator
+     */
+    private static final String POSIX_VALUE_SEP = " ";
+
+    /**
+     * GNU long argument value separator
+     */
+    private static final String GNU_LONG_VALUE_SEP = "=";
+
+    /**
+     * {@inheritDoc}
+     */
+    public Map<String, String> parse(String[] args) {
+        Map<String, String> argMap = new HashMap<>();
+        // parse arguments
+        for (int i = 0; i < args.length;) {
+            if (args[i] == null) {
+                // just to be sure
+                i++;
+                continue;
+            }
+
+            String name = null;
+            String value = null;
+
+            if (isGnuLongArg(args[i])) {
+                // parse GNU long argument
+                name = parseGnuLongArgName(args[i]);
+                value = parseGnuLongArgValue(args[i]);
+            } else if (isPosixArg(args[i])) {
+                // parse POSIX argument
+                name = args[i];
+                if (i + 1 < args.length) {
+                    if (!isPosixArg(args[i + 1]) && !isGnuLongArg(args[i + 
1])) {
+                        // argument has a value
+                        value = args[i + 1];
+                        i++;
+                    }
+                }
+            } else {
+                // invalid argument format
+                throw new IllegalArgumentException(args[i]);
+            }
+
+            argMap.put(name, value);
+            i++;
+        }
+        return argMap;
+    }
+
+    /**
+     * Tests if specified argument contains valid POSIX argument name
+     *
+     * @param arg
+     *            argument
+     * @return {@code true} if string contains valid POSIX argument, otherwise 
{@code false}
+     */
+    private boolean isPosixArg(String arg) {
+        boolean result = true;
+        if (arg == null || arg.length() != 2) {
+            result = false;
+        } else if (!arg.startsWith(PREFIX_POSIX)) {
+            result = false;
+        } else if (!Character.isLetterOrDigit(arg.charAt(1))) {
+            result = false;
+        }
+        return result;
+    }
+
+    /**
+     * Tests if specified argument contains valid GNU long argument name.
+     *
+     * @param arg
+     *            argument
+     * @param value
+     *            {@code true} if argument may contain value, otherwise {@code 
false}
+     * @return {@code true} if string contains valid GNU long argument, 
otherwise {@code false}
+     */
+    private boolean isGnuLongArg(String arg) {
+        boolean result = true;
+        if (arg == null || arg.length() < 3) {
+            result = false;
+        } else if (!arg.startsWith(PREFIX_GNU_LONG)) {
+            result = false;
+        } else {
+            for (int i = 2; i < arg.length(); i++) {
+                if (i > 2 && i + 2 < arg.length() && 
GNU_LONG_VALUE_SEP.equals(arg.substring(i, i + 1))) {
+                    // argument contains value
+                    break;
+                }
+                char c = arg.charAt(i);
+                if (!Character.isLetterOrDigit(c) && c != '-') {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Parses name of GNU long argument from specified string. Method DOES NOT 
validate argument, it just creates
+     * substring from start to value separator (or to the end if separator is 
not present)
+     *
+     * @param str
+     *            specified string
+     * @returns GNU long argument name
+     */
+    private String parseGnuLongArgName(String str) {
+        int idx = str.indexOf(GNU_LONG_VALUE_SEP);
+        if (idx == -1) {
+            // argument does not contain value
+            return str;
+        } else {
+            return str.substring(0, idx);
+        }
+    }
+
+    /**
+     * Parses value of GNU long argument from specified string. Method DOES 
NOT validate argument, it just creates
+     * substring value separator to the end or returns {@code null} if value 
separator is not present
+     *
+     * @param str
+     *            specified string
+     * @returns GNU long argument value or {@code null}
+     */
+    private String parseGnuLongArgValue(String str) {
+        int idx = str.indexOf(GNU_LONG_VALUE_SEP);
+        if (idx == -1) {
+            // arg does not contain value
+            return null;
+        } else {
+            return str.substring(idx + 1);
+        }
+    }
+}
diff --git 
a/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/cli/ExtendedCliParserTest.java
 
b/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/cli/ExtendedCliParserTest.java
new file mode 100644
index 0000000..b0f515a
--- /dev/null
+++ 
b/backend/manager/modules/utils/src/test/java/org/ovirt/engine/core/utils/cli/ExtendedCliParserTest.java
@@ -0,0 +1,175 @@
+package org.ovirt.engine.core.utils.cli;
+
+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;
+
+import java.util.Map;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Parsing POSIX and GNU long arguments with {@code ExtendedCliParser} tests
+ */
+@RunWith(JUnit4.class)
+public class ExtendedCliParserTest {
+    /**
+     * Tests parsing empty arguments
+     */
+    @Test
+    public void emptyArgs() {
+        Map<String, String> results;
+        ExtendedCliParser parser = new ExtendedCliParser();
+
+        final String[] args = {};
+
+        results = parser.parse(args);
+
+        assertNotNull(results);
+        assertTrue(results.isEmpty());
+    }
+
+    /**
+     * Tests parsing POSIX argument without value
+     */
+    @Test
+    public void posixArgWithoutValue() {
+        Map<String, String> results;
+        ExtendedCliParser parser = new ExtendedCliParser();
+        String argName = "-h";
+
+        final String[] args = { argName };
+
+        results = parser.parse(args);
+
+        assertNotNull(results);
+        assertFalse(results.isEmpty());
+
+        assertTrue(results.containsKey(argName));
+        assertNull(results.get(argName));
+    }
+
+    /**
+     * Tests parsing POSIX argument with value
+     */
+    @Test
+    public void posixArgWithValue() {
+        Map<String, String> results;
+        ExtendedCliParser parser = new ExtendedCliParser();
+        String argName = "-f";
+        String argValue = "/tmp/xxx.txt";
+
+        final String[] args = { argName, argValue };
+
+        results = parser.parse(args);
+
+        assertNotNull(results);
+        assertFalse(results.isEmpty());
+
+        assertTrue(results.containsKey(argName));
+        assertEquals(argValue, results.get(argName));
+    }
+
+    /**
+     * Tests parsing GNU long argument without value
+     */
+    @Test
+    public void gnuLongArWithoutValue() {
+        Map<String, String> results;
+        ExtendedCliParser parser = new ExtendedCliParser();
+        String argName = "--help";
+
+        final String[] args = { argName };
+
+        results = parser.parse(args);
+
+        assertNotNull(results);
+        assertFalse(results.isEmpty());
+
+        assertTrue(results.containsKey(argName));
+        assertNull(results.get(argName));
+    }
+
+    /**
+     * Tests parsing GNU long argument with value
+     */
+    @Test
+    public void gnuLongArgWithValue() {
+        Map<String, String> results;
+        ExtendedCliParser parser = new ExtendedCliParser();
+        String argName = "--file";
+        String argValue = "/tmp/xxx.txt";
+
+        final String[] args = { argName + "=" + argValue };
+
+        results = parser.parse(args);
+
+        assertNotNull(results);
+        assertFalse(results.isEmpty());
+
+        assertTrue(results.containsKey(argName));
+        assertEquals(argValue, results.get(argName));
+    }
+
+    /**
+     * Tests parsing POSIX argument with value delimited by GNU long argument 
value separator
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void posixArgWithGnuValueSep() {
+        ExtendedCliParser parser = new ExtendedCliParser();
+        String argName = "-f";
+        String argValue = "/tmp/xxx.txt";
+
+        final String[] args = { argName + "=" + argValue };
+
+        parser.parse(args);
+    }
+
+    /**
+     * Tests parsing GNU long argument with value delimited by POSIX argument 
value separator
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void gnuLongArgWithPosixValueSep() {
+        ExtendedCliParser parser = new ExtendedCliParser();
+        String argName = "--file";
+        String argValue = "/tmp/xxx.txt";
+
+        final String[] args = { argName, argValue };
+
+        parser.parse(args);
+    }
+
+    /**
+     * Tries to parse argument with specified invalid name
+     *
+     * @param name
+     *            invalid argument name
+     */
+    protected void invalidArgName(String name) {
+        try {
+            ExtendedCliParser parser = new ExtendedCliParser();
+            parser.parse(new String[] {name});
+            fail("IllegalArgumentException expected for '" + name + "' 
argument!");
+        } catch (IllegalArgumentException ex) {
+        }
+    }
+
+    /**
+     * Tests arguments with invalid names
+     */
+    @Test
+    public void invalidArgName() {
+        invalidArgName("\t ");
+        invalidArgName("A");
+        invalidArgName("- ");
+        invalidArgName("-test");
+        invalidArgName("--");
+        invalidArgName("--?");
+        invalidArgName("--force=");
+    }
+}


-- 
To view, visit http://gerrit.ovirt.org/19128
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If0dd854826433b577b902eaba6b4fcd8967d1199
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Martin Peřina <mper...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to