ch.threema.apitool.ConsoleMain.java Source code

Java tutorial

Introduction

Here is the source code for ch.threema.apitool.ConsoleMain.java

Source

/*
 * $Id$
 *
 * The MIT License (MIT)
 * Copyright (c) 2015 Threema GmbH
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE
 */
package ch.threema.apitool;

import ch.threema.apitool.console.commands.*;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Command line interface for {@link CryptTool} and {@link APIConnector} operations
 * for testing purposes and simple invocation from other programming languages.
 */
public class ConsoleMain {

    static class Commands {
        protected final List<CommandGroup> commandGroups = new ArrayList<>();

        public CommandGroup create(String description) {
            CommandGroup g = new CommandGroup(description);
            this.commandGroups.add(g);
            return g;
        }

        public ArgumentCommand find(String... arguments) {
            if (arguments.length > 0) {
                for (CommandGroup g : this.commandGroups) {
                    ArgumentCommand c = g.find(arguments);
                    if (c != null) {
                        return c;
                    }
                }
            }
            return null;
        }
    }

    static class CommandGroup {
        protected final String description;
        protected List<ArgumentCommand> argumentCommands = new ArrayList<>();

        CommandGroup(String description) {
            this.description = description;
        }

        public CommandGroup add(Command command, String... arguments) {
            this.argumentCommands.add(new ArgumentCommand(arguments, command));
            return this;
        }

        public ArgumentCommand find(String... arguments) {
            ArgumentCommand matchedArgumentCommand = null;
            int argMatchedSize = -1;
            for (ArgumentCommand c : this.argumentCommands) {
                boolean matched = true;
                int matchedSize = 0;
                for (int n = 0; n < c.arguments.length; n++) {
                    if (n > arguments.length || !c.arguments[n].equals(arguments[n])) {
                        matched = false;
                        break;
                    } else {
                        matchedSize++;
                    }
                }

                if (matched && matchedSize > argMatchedSize) {
                    matchedArgumentCommand = c;
                    argMatchedSize = matchedSize;
                }

            }
            return matchedArgumentCommand;
        }
    }

    static class ArgumentCommand {
        protected final String[] arguments;
        protected final Command command;

        ArgumentCommand(String[] arguments, Command command) {
            this.arguments = arguments;
            this.command = command;
        }

        public void run(String[] givenArguments) throws Exception {
            if (givenArguments.length < this.arguments.length) {
                throw new IllegalArgumentException("invalid arguments");
            }

            this.command.run(
                    (String[]) ArrayUtils.subarray(givenArguments, this.arguments.length, givenArguments.length));
        }
    }

    private static final Commands commands = new Commands();

    public static void main(String[] args) throws Exception {

        commands.create("Local operations (no network communication)").add(new EncryptCommand(), "-e")
                .add(new DecryptCommand(), "-d").add(new HashEmailCommand(), "-h", "-e")
                .add(new HashPhoneCommand(), "-h", "-p").add(new GenerateKeyPairCommand(), "-g")
                .add(new DerivePublicKeyCommand(), "-p").add(new VersionCommand(), "-v");

        commands.create("Network operations").add(new SendSimpleMessageCommand(), "-s")
                .add(new SendE2ETextMessageCommand(), "-S").add(new SendE2EImageMessageCommand(), "-S", "-i")
                .add(new SendE2EFileMessageCommand(), "-S", "-f").add(new IDLookupByEmail(), "-l", "-e")
                .add(new IDLookupByPhoneNo(), "-l", "-p").add(new FetchPublicKey(), "-l", "-k")
                .add(new CapabilityCommand(), "-c").add(new DecryptAndDownloadCommand(), "-D")
                .add(new CreditsCommand(), "-C");

        ArgumentCommand argumentCommand = commands.find(args);
        if (argumentCommand == null) {
            usage(args.length == 1 && args[0].equals("html"));
        } else {
            argumentCommand.run(args);
        }
    }

    private static void usage(boolean htmlOutput) {
        if (!htmlOutput) {
            System.out.println("version:" + ConsoleMain.class.getPackage().getImplementationVersion());

            System.out.println("usage:\n");

            System.out.println("General information");
            System.out.println("-------------------\n");

            System.out.println("Where a key needs to be specified, it can either be given directly as");
            System.out.println("a command line parameter (in hex with a prefix indicating the type;");
            System.out.println("not recommended on shared machines as other users may be able to see");
            System.out.println("the arguments), or as the path to a file that it should be read from");
            System.out.println("(file contents also in hex with the prefix).\n");
        }

        String groupDescriptionTemplate = htmlOutput ? "<h3>%s</h3>\n"
                : "\n%s\n" + StringUtils.repeat("-", 80) + "\n\n";
        String commandTemplate = htmlOutput ? "<pre><code>java -jar threema-msgapi-tool.jar %s</code></pre>\n"
                : "%s\n";

        for (CommandGroup commandGroup : commands.commandGroups) {
            System.out.format(groupDescriptionTemplate, commandGroup.description);

            for (ArgumentCommand argumentCommand : commandGroup.argumentCommands) {
                StringBuilder command = new StringBuilder();
                for (int n = 0; n < argumentCommand.arguments.length; n++) {
                    command.append(argumentCommand.arguments[n]).append(" ");
                }
                String argumentDescription = argumentCommand.command.getUsageArguments();
                if (htmlOutput) {
                    System.out.format("<h4>%s</h4>\n", argumentCommand.command.getSubject());
                    argumentDescription = StringEscapeUtils.escapeHtml(argumentDescription);
                }
                command.append(argumentDescription);

                System.out.format(commandTemplate, command.toString().trim());

                String description = argumentCommand.command.getUsageDescription();
                if (htmlOutput) {
                    System.out.format("<p>%s</p>\n\n", description);
                } else {
                    System.out.println("   " + WordUtils.wrap(description, 76, "\n   ", false));
                    System.out.println("");
                }
            }
        }
    }
}