From ddcb4847df9c9c04e1c8a118f99655a4a93cda40 Mon Sep 17 00:00:00 2001
From: Jean Chalard <jchalard@google.com>
Date: Mon, 28 May 2012 17:30:18 +0900
Subject: [PATCH] Add a tool to do intendance tasks on dictionaries.

Bug: 6429606
Change-Id: I0c7258d992a4bfa9707002f8fbc425ccde7c6172
---
 tools/dicttool/Android.mk                     |  25 ++++
 tools/dicttool/etc/Android.mk                 |  20 +++
 tools/dicttool/etc/dicttool                   |  62 +++++++++
 tools/dicttool/etc/manifest.txt               |   1 +
 .../inputmethod/latin/dicttool/Compress.java  |  94 ++++++++++++++
 .../inputmethod/latin/dicttool/Dicttool.java  | 120 ++++++++++++++++++
 .../inputmethod/latin/dicttool/Info.java      |  35 +++++
 7 files changed, 357 insertions(+)
 create mode 100644 tools/dicttool/Android.mk
 create mode 100644 tools/dicttool/etc/Android.mk
 create mode 100755 tools/dicttool/etc/dicttool
 create mode 100644 tools/dicttool/etc/manifest.txt
 create mode 100644 tools/dicttool/src/android/inputmethod/latin/dicttool/Compress.java
 create mode 100644 tools/dicttool/src/android/inputmethod/latin/dicttool/Dicttool.java
 create mode 100644 tools/dicttool/src/android/inputmethod/latin/dicttool/Info.java

diff --git a/tools/dicttool/Android.mk b/tools/dicttool/Android.mk
new file mode 100644
index 0000000000..9e8dbe0f81
--- /dev/null
+++ b/tools/dicttool/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_JAR_MANIFEST := etc/manifest.txt
+LOCAL_MODULE := dicttool
+LOCAL_MODULE_TAGS := eng
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+include $(LOCAL_PATH)/etc/Android.mk
diff --git a/tools/dicttool/etc/Android.mk b/tools/dicttool/etc/Android.mk
new file mode 100644
index 0000000000..03d4a96eec
--- /dev/null
+++ b/tools/dicttool/etc/Android.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := eng
+LOCAL_PREBUILT_EXECUTABLES := dicttool
+include $(BUILD_HOST_PREBUILT)
diff --git a/tools/dicttool/etc/dicttool b/tools/dicttool/etc/dicttool
new file mode 100755
index 0000000000..8a39694f72
--- /dev/null
+++ b/tools/dicttool/etc/dicttool
@@ -0,0 +1,62 @@
+#!/bin/sh
+# Copyright 2011, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=dicttool.jar
+frameworkdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# might need more memory, e.g. -Xmx128M
+exec java -ea -jar "$jarpath" "$@"
diff --git a/tools/dicttool/etc/manifest.txt b/tools/dicttool/etc/manifest.txt
new file mode 100644
index 0000000000..67c85214c1
--- /dev/null
+++ b/tools/dicttool/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.inputmethod.latin.dicttool.Dicttool
diff --git a/tools/dicttool/src/android/inputmethod/latin/dicttool/Compress.java b/tools/dicttool/src/android/inputmethod/latin/dicttool/Compress.java
new file mode 100644
index 0000000000..307f5964c8
--- /dev/null
+++ b/tools/dicttool/src/android/inputmethod/latin/dicttool/Compress.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin.dicttool;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+public class Compress {
+
+    private static OutputStream getCompressedStream(final OutputStream out)
+        throws java.io.IOException {
+        return new GZIPOutputStream(out);
+    }
+
+    private static InputStream getUncompressedStream(final InputStream in) throws IOException {
+        return new GZIPInputStream(in);
+    }
+
+    public static void copy(final InputStream input, final OutputStream output) throws IOException {
+        final byte[] buffer = new byte[1000];
+        for (int readBytes = input.read(buffer); readBytes >= 0; readBytes = input.read(buffer))
+            output.write(buffer, 0, readBytes);
+        input.close();
+        output.close();
+    }
+
+    static public class Compressor extends Dicttool.Command {
+        public static final String COMMAND = "compress";
+        private static final String SUFFIX = ".compressed";
+
+        public Compressor() {
+        }
+
+        public String getHelp() {
+            return "compress <filename>: Compresses a file using gzip compression";
+        }
+
+        public int getArity() {
+            return 1;
+        }
+
+        public void run() throws IOException {
+            final String inFilename = mArgs[0];
+            final String outFilename = inFilename + SUFFIX;
+            final FileInputStream input = new FileInputStream(new File(inFilename));
+            final FileOutputStream output = new FileOutputStream(new File(outFilename));
+            copy(input, new GZIPOutputStream(output));
+        }
+    }
+
+    static public class Uncompressor extends Dicttool.Command {
+        public static final String COMMAND = "uncompress";
+        private static final String SUFFIX = ".uncompressed";
+
+        public Uncompressor() {
+        }
+
+        public String getHelp() {
+            return "uncompress <filename>: Uncompresses a file compressed with gzip compression";
+        }
+
+        public int getArity() {
+            return 1;
+        }
+
+        public void run() throws IOException {
+            final String inFilename = mArgs[0];
+            final String outFilename = inFilename + SUFFIX;
+            final FileInputStream input = new FileInputStream(new File(inFilename));
+            final FileOutputStream output = new FileOutputStream(new File(outFilename));
+            copy(new GZIPInputStream(input), output);
+        }
+    }
+}
diff --git a/tools/dicttool/src/android/inputmethod/latin/dicttool/Dicttool.java b/tools/dicttool/src/android/inputmethod/latin/dicttool/Dicttool.java
new file mode 100644
index 0000000000..b78be79756
--- /dev/null
+++ b/tools/dicttool/src/android/inputmethod/latin/dicttool/Dicttool.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin.dicttool;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+public class Dicttool {
+
+    public static abstract class Command {
+        protected String[] mArgs;
+        public void setArgs(String[] args) throws IllegalArgumentException {
+            mArgs = args;
+        }
+        abstract public int getArity();
+        abstract public String getHelp();
+        abstract public void run() throws Exception;
+    }
+    static HashMap<String, Class<? extends Command>> sCommands =
+            new HashMap<String, Class<? extends Command>>();
+    static {
+        sCommands.put("info", Info.class);
+        sCommands.put("compress", Compress.Compressor.class);
+        sCommands.put("uncompress", Compress.Uncompressor.class);
+    }
+
+    private static Command getCommandInstance(final String commandName) {
+        try {
+            return sCommands.get(commandName).newInstance();
+        } catch (InstantiationException e) {
+            throw new RuntimeException(commandName + " is not installed");
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(commandName + " is not installed");
+        }
+    }
+
+    private static void help() {
+        System.out.println("Syntax: dicttool <command [arguments]>\nAvailable commands:\n");
+        for (final String commandName : sCommands.keySet()) {
+            System.out.println("*** " + commandName);
+            System.out.println(getCommandInstance(commandName).getHelp());
+            System.out.println("");
+        }
+    }
+
+    private static boolean isCommand(final String commandName) {
+        return sCommands.containsKey(commandName);
+    }
+
+    private String mPreviousCommand = null; // local to the getNextCommand function
+    private Command getNextCommand(final ArrayList<String> arguments) {
+        final String firstArgument = arguments.get(0);
+        final String commandName;
+        if (isCommand(firstArgument)) {
+            commandName = firstArgument;
+            arguments.remove(0);
+        } else if (isCommand(mPreviousCommand)) {
+            commandName = mPreviousCommand;
+        } else {
+            throw new RuntimeException("Unknown command : " + firstArgument);
+        }
+        final Command command = getCommandInstance(commandName);
+        final int arity = command.getArity();
+        if (arguments.size() < arity) {
+            throw new RuntimeException("Not enough arguments to command " + commandName);
+        }
+        final String[] argsArray = new String[arity];
+        arguments.subList(0, arity).toArray(argsArray);
+        for (int i = 0; i < arity; ++i) {
+            // For some reason, ArrayList#removeRange is protected
+            arguments.remove(0);
+        }
+        command.setArgs(argsArray);
+        mPreviousCommand = commandName;
+        return command;
+    }
+
+    private void execute(final ArrayList<String> arguments) {
+        ArrayList<Command> commandsToExecute = new ArrayList<Command>();
+        while (!arguments.isEmpty()) {
+            commandsToExecute.add(getNextCommand(arguments));
+        }
+        for (final Command command : commandsToExecute) {
+            try {
+                command.run();
+            } catch (Exception e) {
+                System.out.println("Exception while processing command "
+                        + command.getClass().getSimpleName() + " : " + e);
+                return;
+            }
+        }
+    }
+
+    public static void main(final String[] args) {
+        if (0 == args.length) {
+            help();
+            return;
+        }
+        if (!isCommand(args[0])) throw new RuntimeException("Unknown command : " + args[0]);
+
+        final ArrayList<String> arguments = new ArrayList<String>(args.length);
+        arguments.addAll(Arrays.asList(args));
+        new Dicttool().execute(arguments);
+    }
+}
diff --git a/tools/dicttool/src/android/inputmethod/latin/dicttool/Info.java b/tools/dicttool/src/android/inputmethod/latin/dicttool/Info.java
new file mode 100644
index 0000000000..cb032dd3b3
--- /dev/null
+++ b/tools/dicttool/src/android/inputmethod/latin/dicttool/Info.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin.dicttool;
+
+public class Info extends Dicttool.Command {
+    public Info() {
+    }
+
+    public String getHelp() {
+        return "info <filename>: prints various information about a dictionary file";
+    }
+
+    public int getArity() {
+        return 1;
+    }
+
+    public void run() {
+        // TODO: implement this
+        System.out.println("Not implemented yet");
+    }
+}
-- 
GitLab