changeset 199:f2ce7773b93c

Implement CLI framework. Reviewed-by: neugens, vanaltj Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-April/000681.html
author Roman Kennke <rkennke@redhat.com>
date Wed, 04 Apr 2012 21:47:57 +0200
parents 4a33f41c7782
children 18fdcb51a38e
files cli/pom.xml cli/src/main/java/com/redhat/thermostat/cli/Command.java cli/src/main/java/com/redhat/thermostat/cli/CommandContext.java cli/src/main/java/com/redhat/thermostat/cli/CommandContextFactory.java cli/src/main/java/com/redhat/thermostat/cli/CommandContextFactoryImpl.java cli/src/main/java/com/redhat/thermostat/cli/CommandContextImpl.java cli/src/main/java/com/redhat/thermostat/cli/CommandRegistry.java cli/src/main/java/com/redhat/thermostat/cli/Console.java cli/src/main/java/com/redhat/thermostat/cli/Main.java cli/src/main/java/com/redhat/thermostat/cli/SystemConsole.java cli/src/main/resources/META-INF/services/com.redhat.thermostat.cli.Command cli/src/test/java/com/redhat/thermostat/cli/CLITestEnvironment.java cli/src/test/java/com/redhat/thermostat/cli/CommandContextFactoryTest.java cli/src/test/java/com/redhat/thermostat/cli/CommandRegistryTest.java cli/src/test/java/com/redhat/thermostat/cli/MainTest.java cli/src/test/java/com/redhat/thermostat/cli/TestCommandContextFactory.java
diffstat 16 files changed, 969 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/pom.xml	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+
+ Copyright 2012 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.redhat.thermostat</groupId>
+    <artifactId>thermostat</artifactId>
+    <version>0.2-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <artifactId>thermostat-cli</artifactId>
+  <packaging>jar</packaging>
+
+  <name>Thermostat CLI</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+  </dependencies>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/java/com/redhat/thermostat/cli/Command.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012 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.cli;
+
+interface Command {
+
+    void run(CommandContext ctx);
+
+    String getName();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/java/com/redhat/thermostat/cli/CommandContext.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012 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.cli;
+
+interface CommandContext {
+
+    Console getConsole();
+
+    String[] getArguments();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/java/com/redhat/thermostat/cli/CommandContextFactory.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012 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.cli;
+
+abstract class CommandContextFactory {
+
+    private static CommandContextFactory instance = new CommandContextFactoryImpl();
+
+    static CommandContextFactory getInstance() {
+        return instance;
+    }
+
+    static void setInstance(CommandContextFactory ctxFactory) {
+        instance = ctxFactory;
+    }
+
+    abstract CommandContext createContext(String[] args);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/java/com/redhat/thermostat/cli/CommandContextFactoryImpl.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012 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.cli;
+
+class CommandContextFactoryImpl extends CommandContextFactory {
+
+    @Override
+    CommandContext createContext(final String[] args) {
+        return new CommandContextImpl(args);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/java/com/redhat/thermostat/cli/CommandContextImpl.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 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.cli;
+
+class CommandContextImpl implements CommandContext {
+
+    private String[] arguments;
+
+    CommandContextImpl(String[] args) {
+        arguments = args;
+    }
+
+    @Override
+    public Console getConsole() {
+        return new SystemConsole();
+    }
+
+    @Override
+    public String[] getArguments() {
+        return arguments;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/java/com/redhat/thermostat/cli/CommandRegistry.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2012 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.cli;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class CommandRegistry {
+
+    private static CommandRegistry instance = new CommandRegistry();
+
+    static CommandRegistry getInstance() {
+        return instance;
+    }
+
+    static void setInstance(CommandRegistry commandRegistry) {
+        instance = commandRegistry;
+    }
+
+    private Map<String,Command> commands;
+
+    CommandRegistry() {
+        commands = new HashMap<>();
+    }
+
+    private void registerCommand(Command cmd) {
+        commands.put(cmd.getName(), cmd);
+    }
+
+    void registerCommands(Iterable<Command> cmds) {
+        for (Command cmd : cmds) {
+            registerCommand(cmd);
+        }
+    }
+
+    Command getCommand(String name) {
+        return commands.get(name);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/java/com/redhat/thermostat/cli/Console.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 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.cli;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+
+public interface Console {
+
+    PrintStream getOutput();
+
+    PrintStream getError();
+
+    InputStream getInput();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/java/com/redhat/thermostat/cli/Main.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012 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.cli;
+
+import java.util.Arrays;
+import java.util.ServiceLoader;
+
+public class Main {
+
+    public static void main(String[] args) {
+        new Main().run(args);
+    }
+
+    private void run(String[] args) {
+        ServiceLoader<Command> cmds = ServiceLoader.load(Command.class);
+        CommandRegistry registry = CommandRegistry.getInstance();
+        registry.registerCommands(cmds);
+        Command cmd = registry.getCommand(args[0]);
+        CommandContext ctx = CommandContextFactory.getInstance().createContext(Arrays.copyOfRange(args, 1, args.length));
+        cmd.run(ctx);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/java/com/redhat/thermostat/cli/SystemConsole.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2012 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.cli;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+
+class SystemConsole implements Console {
+
+    @Override
+    public PrintStream getOutput() {
+        return System.out;
+    }
+
+    @Override
+    public PrintStream getError() {
+        return System.err;
+    }
+
+    @Override
+    public InputStream getInput() {
+        return System.in;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/main/resources/META-INF/services/com.redhat.thermostat.cli.Command	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,1 @@
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/test/java/com/redhat/thermostat/cli/CLITestEnvironment.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012 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.cli;
+
+public class CLITestEnvironment {
+
+    public static void setUp() {
+        reset();
+    }
+
+    public static void tearDown() {
+        reset();
+    }
+
+    private static void reset() {
+        CommandContextFactory.setInstance(new CommandContextFactoryImpl());
+        CommandRegistry.setInstance(new CommandRegistry());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/test/java/com/redhat/thermostat/cli/CommandContextFactoryTest.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012 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.cli;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class CommandContextFactoryTest {
+
+    @Test
+    public void testDefaultInstance() {
+        CommandContextFactory cmdCtxFactory = CommandContextFactory.getInstance();
+        CommandContext ctx = cmdCtxFactory.createContext(new String[] {"arg1", "arg2"});
+        assertSame(System.out, ctx.getConsole().getOutput());
+        assertSame(System.err, ctx.getConsole().getError());
+        assertSame(System.in, ctx.getConsole().getInput());
+        assertArrayEquals(new String[] {"arg1", "arg2"}, ctx.getArguments());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/test/java/com/redhat/thermostat/cli/CommandRegistryTest.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012 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.cli;
+
+import java.util.Arrays;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.mockito.Mockito.*;
+
+public class CommandRegistryTest {
+
+    private CommandRegistry registry;
+    private Command cmd1;
+    private Command cmd2;
+
+    @Before
+    public void setUp() {
+        registry = new CommandRegistry();
+        cmd1 = createCommand("test1");
+        cmd2 = createCommand("test2");
+        registry.registerCommands(Arrays.asList(cmd1, cmd2));
+    }
+
+    @After
+    public void tearDown() {
+        cmd2 = null;
+        cmd1 = null;
+        registry = null;
+    }
+
+    private Command createCommand(String name) {
+        Command cmd = mock(Command.class);
+        when(cmd.getName()).thenReturn(name);
+        return cmd;
+    }
+
+    @Test
+    public void testRegisterCommands() {
+        runAndVerifyCommand("test1", cmd1);
+        runAndVerifyCommand("test2", cmd2);
+    }
+
+    private void runAndVerifyCommand(String name, Command cmd) {
+        Command actualCmd = registry.getCommand(name);
+        TestCommandContextFactory cf = new TestCommandContextFactory();
+        CommandContext ctx = cf.createContext(new String[0]);
+        actualCmd.run(ctx);
+        verify(cmd).run(ctx);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/test/java/com/redhat/thermostat/cli/MainTest.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2012 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.cli;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MainTest {
+
+    private static class TestCmd1 implements Command {
+
+        @Override
+        public void run(CommandContext ctx) {
+            String arg1 = ctx.getArguments()[0];
+            String arg2 = ctx.getArguments()[1];
+            ctx.getConsole().getOutput().print(arg1 + ", " + arg2);
+        }
+
+        @Override
+        public String getName() {
+            return "test1";
+        }
+
+    }
+
+    private static class TestCmd2 implements Command {
+
+        @Override
+        public void run(CommandContext ctx) {
+            String arg1 = ctx.getArguments()[0];
+            String arg2 = ctx.getArguments()[1];
+            ctx.getConsole().getOutput().print(arg2 + ": " + arg1);
+        }
+
+        @Override
+        public String getName() {
+            return "test2";
+        }
+
+    }
+
+    private TestCommandContextFactory  ctxFactory;
+
+    @Before
+    public void setUp() {
+
+        CLITestEnvironment.setUp();
+        ctxFactory = new TestCommandContextFactory();
+        CommandContextFactory.setInstance(ctxFactory);
+
+        CommandRegistry.getInstance().registerCommands(Arrays.asList(new TestCmd1(), new TestCmd2()));
+
+    }
+
+    @After
+    public void tearDown() {
+        CLITestEnvironment.tearDown();
+    }
+
+    @Test
+    public void testMain() {
+        runAndVerifyCommand(new String[] {"test1", "Hello", "World"}, "Hello, World");
+
+        ctxFactory.reset();
+
+        runAndVerifyCommand(new String[] {"test2", "Hello", "World"}, "World: Hello");
+    }
+
+    private void runAndVerifyCommand(String[] args, String expected) {
+        Main.main(args);
+        assertEquals(expected, ctxFactory.getOutput());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli/src/test/java/com/redhat/thermostat/cli/TestCommandContextFactory.java	Wed Apr 04 21:47:57 2012 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2012 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.cli;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+
+class TestCommandContextFactory extends CommandContextFactory {
+
+    private ByteArrayOutputStream out = new ByteArrayOutputStream();
+    private ByteArrayOutputStream err = new ByteArrayOutputStream();
+    private ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]);
+
+    private class TestConsole implements Console {
+
+        @Override
+        public PrintStream getOutput() {
+            return new PrintStream(out);
+        }
+
+        @Override
+        public PrintStream getError() {
+            return new PrintStream(err);
+        }
+
+        @Override
+        public InputStream getInput() {
+            return in;
+        }
+        
+    }
+
+    @Override
+    CommandContext createContext(final String[] args) {
+        return new CommandContext() {
+
+            @Override
+            public Console getConsole() {
+                return new TestConsole();
+            }
+
+            @Override
+            public String[] getArguments() {
+                return args;
+            }
+            
+        };
+    }
+
+    public Object getOutput() {
+        return new String(out.toByteArray());
+    }
+
+    public void setInput(String input) {
+        in = new ByteArrayInputStream(input.getBytes());
+    }
+
+    public Object getError() {
+        return new String(err.toByteArray());
+    }
+
+    public void reset() {
+        out = new ByteArrayOutputStream();
+        err = new ByteArrayOutputStream();
+    }
+}