1/**
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17package com.android.inputmethod.latin.dicttool;
18
19import java.io.BufferedInputStream;
20import java.io.BufferedOutputStream;
21import java.io.File;
22import java.io.FileInputStream;
23import java.io.FileNotFoundException;
24import java.io.FileOutputStream;
25import java.io.InputStream;
26import java.io.OutputStream;
27import java.util.Arrays;
28import java.util.HashMap;
29
30public class Dicttool {
31
32    public static abstract class Command {
33        public static final String STDIN_OR_STDOUT = "-";
34        protected String[] mArgs;
35
36        public void setArgs(String[] args) throws IllegalArgumentException {
37            mArgs = args;
38        }
39
40        protected static InputStream getFileInputStreamOrStdIn(final String inFilename)
41                throws FileNotFoundException {
42            if (STDIN_OR_STDOUT.equals(inFilename)) {
43                return System.in;
44            }
45            return getFileInputStream(new File(inFilename));
46        }
47
48        protected static InputStream getFileInputStream(final File inFile)
49                throws FileNotFoundException {
50            return new BufferedInputStream(new FileInputStream(inFile));
51        }
52
53        protected static OutputStream getFileOutputStreamOrStdOut(final String outFilename)
54                throws FileNotFoundException {
55            if (STDIN_OR_STDOUT.equals(outFilename)) {
56                return System.out;
57            }
58            return getFileOutputStream(new File(outFilename));
59        }
60
61        protected static OutputStream getFileOutputStream(final File outFile)
62                throws FileNotFoundException {
63            return new BufferedOutputStream(new FileOutputStream(outFile));
64        }
65
66        abstract public String getHelp();
67        abstract public void run() throws Exception;
68    }
69
70    static HashMap<String, Class<? extends Command>> sCommands = new HashMap<>();
71
72    static {
73        CommandList.populate();
74    }
75
76    public static void addCommand(final String commandName, final Class<? extends Command> cls) {
77        sCommands.put(commandName, cls);
78    }
79
80    private static Command getCommandInstance(final String commandName) {
81        try {
82            return sCommands.get(commandName).newInstance();
83        } catch (InstantiationException e) {
84            throw new RuntimeException(commandName + " is not installed");
85        } catch (IllegalAccessException e) {
86            throw new RuntimeException(commandName + " is not installed");
87        }
88    }
89
90    private static void help() {
91        System.out.println("Syntax: dicttool <command [arguments]>\nAvailable commands:\n");
92        for (final String commandName : sCommands.keySet()) {
93            System.out.println("*** " + commandName);
94            System.out.println(getCommandInstance(commandName).getHelp());
95            System.out.println("");
96        }
97    }
98
99    private static boolean isCommand(final String commandName) {
100        return sCommands.containsKey(commandName);
101    }
102
103    private static Command getCommand(final String[] arguments) {
104        final String commandName = arguments[0];
105        if (!isCommand(commandName)) {
106            throw new RuntimeException("Unknown command : " + commandName);
107        }
108        final Command command = getCommandInstance(commandName);
109        final String[] argsArray = Arrays.copyOfRange(arguments, 1, arguments.length);
110        command.setArgs(argsArray);
111        return command;
112    }
113
114    /**
115     * Executes the specified command with the specified arguments.
116     * @param arguments the arguments passed to dicttool.
117     * @return 0 for success, an error code otherwise (always 1 at the moment)
118     */
119    private static int execute(final String[] arguments) {
120        final Command command = getCommand(arguments);
121        try {
122            command.run();
123            return 0;
124        } catch (Exception e) {
125            System.out.println("Exception while processing command "
126                    + command.getClass().getSimpleName() + " : " + e);
127            e.printStackTrace();
128            return 1;
129        }
130    }
131
132    public static void main(final String[] arguments) {
133        if (0 == arguments.length) {
134            help();
135            return;
136        }
137        // Exit with the success/error code from #execute() as status.
138        System.exit(execute(arguments));
139    }
140}
141