aboutsummaryrefslogtreecommitdiffstats
path: root/tools/make-keyboard-text/src
diff options
context:
space:
mode:
Diffstat (limited to 'tools/make-keyboard-text/src')
-rw-r--r--tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java55
-rw-r--r--tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/JarUtils.java40
-rw-r--r--tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/LocaleUtils.java167
-rw-r--r--tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MakeKeyboardText.java2
-rw-r--r--tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java229
-rw-r--r--tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java35
6 files changed, 378 insertions, 150 deletions
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java
index 331003e67..48bf8010a 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java
@@ -22,17 +22,26 @@ public class ArrayInitializerFormatter {
private final PrintStream mOut;
private final int mMaxWidth;
private final String mIndent;
+ // String resource names array; indexed by {@link #CurrentIndex} and
+ // {@link #mStartIndexOfBuffer}.
+ private final String[] mResourceNames;
private int mCurrentIndex = 0;
- private String mFixedElement;
+ private String mLastElement;
private final StringBuilder mBuffer = new StringBuilder();
private int mBufferedLen;
- private int mBufferedIndex = Integer.MIN_VALUE;
+ private int mStartIndexOfBuffer = Integer.MIN_VALUE;
- public ArrayInitializerFormatter(PrintStream out, int width, String indent) {
+ public ArrayInitializerFormatter(final PrintStream out, final int width, final String indent,
+ final String[] resourceNames) {
mOut = out;
mMaxWidth = width - indent.length();
mIndent = indent;
+ mResourceNames = resourceNames;
+ }
+
+ public int getCurrentIndex() {
+ return mCurrentIndex;
}
public void flush() {
@@ -40,42 +49,48 @@ public class ArrayInitializerFormatter {
return;
}
final int lastIndex = mCurrentIndex - 1;
- if (mBufferedIndex == lastIndex) {
- mOut.format("%s/* %d */ %s\n", mIndent, mBufferedIndex, mBuffer);
- } else if (mBufferedIndex == lastIndex - 1) {
- final String[] elements = mBuffer.toString().split(" ");
- mOut.format("%s/* %d */ %s\n"
- + "%s/* %d */ %s\n",
- mIndent, mBufferedIndex, elements[0],
- mIndent, lastIndex, elements[1]);
+ if (mStartIndexOfBuffer == lastIndex) {
+ mOut.format("%s/* %s */ %s\n",
+ mIndent, mResourceNames[mStartIndexOfBuffer], mBuffer);
+ } else if (mStartIndexOfBuffer == lastIndex - 1) {
+ final String startElement = mBuffer.toString()
+ .substring(0, mBuffer.length() - mLastElement.length())
+ .trim();
+ mOut.format("%s/* %s */ %s\n"
+ + "%s/* %s */ %s\n",
+ mIndent, mResourceNames[mStartIndexOfBuffer], startElement,
+ mIndent, mResourceNames[lastIndex], mLastElement);
} else {
- mOut.format("%s/* %d~ */\n"
+ mOut.format("%s/* %s ~ */\n"
+ "%s%s\n"
- + "%s/* ~%d */\n", mIndent, mBufferedIndex,
+ + "%s/* ~ %s */\n",
+ mIndent, mResourceNames[mStartIndexOfBuffer],
mIndent, mBuffer,
- mIndent, lastIndex);
+ mIndent, mResourceNames[lastIndex]);
}
mBuffer.setLength(0);
mBufferedLen = 0;
}
- public void outCommentLines(String lines) {
+ public void outCommentLines(final String lines) {
flush();
mOut.print(lines);
- mFixedElement = null;
+ mLastElement = null;
}
- public void outElement(String element) {
- if (!element.equals(mFixedElement)) {
+ public void outElement(final String element) {
+ if (!element.equals(mLastElement)) {
flush();
- mBufferedIndex = mCurrentIndex;
+ mStartIndexOfBuffer = mCurrentIndex;
}
final int nextLen = mBufferedLen + " ".length() + element.length();
if (mBufferedLen != 0 && nextLen < mMaxWidth) {
+ // Element can fit in the current line.
mBuffer.append(' ');
mBuffer.append(element);
mBufferedLen = nextLen;
} else {
+ // Element should be on the next line.
if (mBufferedLen != 0) {
mBuffer.append('\n');
mBuffer.append(mIndent);
@@ -84,6 +99,6 @@ public class ArrayInitializerFormatter {
mBufferedLen = element.length();
}
mCurrentIndex++;
- mFixedElement = element;
+ mLastElement = element;
}
}
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/JarUtils.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/JarUtils.java
index a74096e79..abb33397b 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/JarUtils.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/JarUtils.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.keyboard.tools;
+import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
@@ -23,6 +24,7 @@ import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.Locale;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -58,8 +60,8 @@ public final class JarUtils {
public boolean accept(String dirName, String name);
}
- public static ArrayList<String> getNameListing(final JarFile jar, final JarFilter filter) {
- final ArrayList<String> result = new ArrayList<String>();
+ public static ArrayList<String> getEntryNameListing(final JarFile jar, final JarFilter filter) {
+ final ArrayList<String> result = new ArrayList<>();
final Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
@@ -74,12 +76,42 @@ public final class JarUtils {
return result;
}
- public static ArrayList<String> getNameListing(final JarFile jar, final String filterName) {
- return getNameListing(jar, new JarFilter() {
+ public static ArrayList<String> getEntryNameListing(final JarFile jar,
+ final String filterName) {
+ return getEntryNameListing(jar, new JarFilter() {
@Override
public boolean accept(final String dirName, final String name) {
return name.equals(filterName);
}
});
}
+
+ // The locale is taken from string resource jar entry name (values-<locale>/)
+ // or {@link LocaleUtils#DEFAULT_LOCALE} for the default string resource
+ // directory (values/).
+ public static Locale getLocaleFromEntryName(final String jarEntryName) {
+ final String dirName = jarEntryName.substring(0, jarEntryName.lastIndexOf('/'));
+ final int pos = dirName.lastIndexOf('/');
+ final String parentName = (pos >= 0) ? dirName.substring(pos + 1) : dirName;
+ final int localePos = parentName.indexOf('-');
+ if (localePos < 0) {
+ // Default resource name.
+ return LocaleUtils.DEFAULT_LOCALE;
+ }
+ final String localeStr = parentName.substring(localePos + 1);
+ final int regionPos = localeStr.indexOf("-r");
+ if (regionPos < 0) {
+ return LocaleUtils.constructLocaleFromString(localeStr);
+ }
+ return LocaleUtils.constructLocaleFromString(localeStr.replace("-r", "_"));
+ }
+
+ public static void close(final Closeable stream) {
+ try {
+ if (stream != null) {
+ stream.close();
+ }
+ } catch (IOException e) {
+ }
+ }
}
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/LocaleUtils.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/LocaleUtils.java
new file mode 100644
index 000000000..c1a7ec5eb
--- /dev/null
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/LocaleUtils.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2013 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.keyboard.tools;
+
+import java.util.HashMap;
+import java.util.Locale;
+
+/**
+ * A class to help with handling Locales in string form.
+ *
+ * This is a subset of com/android/inputmethod/latin/utils/LocaleUtils.java in order to use
+ * for the make-keyboard-text tool.
+ */
+public final class LocaleUtils {
+ public static final Locale DEFAULT_LOCALE = Locale.ROOT;
+ private static final String DEFAULT_LOCALE_CODE = "DEFAULT";
+ public static final String NO_LANGUAGE_LOCALE_CODE = "zz";
+ public static final String NO_LANGUAGE_LOCALE_DISPLAY_NAME = "Alphabet";
+
+ private LocaleUtils() {
+ // Intentional empty constructor for utility class.
+ }
+
+ private static final HashMap<String, Locale> sLocaleCache = new HashMap<>();
+
+ private static final int INDEX_LANGUAGE = 0;
+ private static final int INDEX_SCRIPT = 1;
+ private static final int INDEX_REGION = 2;
+ private static final int ELEMENT_LIMIT = INDEX_REGION + 1;
+
+ /**
+ * Creates a locale from a string specification.
+ *
+ * Locale string is: language(_script)?(_region)?
+ * where: language := [a-zA-Z]{2,3}
+ * script := [a-zA-Z]{4}
+ * region := [a-zA-Z]{2,3}|[0-9]{3}
+ */
+ public static Locale constructLocaleFromString(final String localeStr) {
+ if (localeStr == null) {
+ return null;
+ }
+ synchronized (sLocaleCache) {
+ if (sLocaleCache.containsKey(localeStr)) {
+ return sLocaleCache.get(localeStr);
+ }
+ boolean hasRegion = false;
+ final Locale.Builder builder = new Locale.Builder();
+ final String[] localeElements = localeStr.split("_", ELEMENT_LIMIT);
+ if (localeElements.length > INDEX_LANGUAGE) {
+ final String text = localeElements[INDEX_LANGUAGE];
+ if (isValidLanguage(text)) {
+ builder.setLanguage(text);
+ } else {
+ throw new RuntimeException("Unknown locale format: " + localeStr);
+ }
+ }
+ if (localeElements.length > INDEX_SCRIPT) {
+ final String text = localeElements[INDEX_SCRIPT];
+ if (isValidScript(text)) {
+ builder.setScript(text);
+ } else if (isValidRegion(text)) {
+ builder.setRegion(text);
+ hasRegion = true;
+ } else {
+ throw new RuntimeException("Unknown locale format: " + localeStr);
+ }
+ }
+ if (localeElements.length > INDEX_REGION) {
+ final String text = localeElements[INDEX_REGION];
+ if (!hasRegion && isValidRegion(text)) {
+ builder.setRegion(text);
+ } else {
+ throw new RuntimeException("Unknown locale format: " + localeStr);
+ }
+ }
+ final Locale locale = builder.build();
+ sLocaleCache.put(localeStr, locale);
+ return locale;
+ }
+ }
+
+ private static final int MIN_LENGTH_OF_LANGUAGE = 2;
+ private static final int MAX_LENGTH_OF_LANGUAGE = 2;
+ private static final int LENGTH_OF_SCRIPT = 4;
+ private static final int MIN_LENGTH_OF_REGION = 2;
+ private static final int MAX_LENGTH_OF_REGION = 2;
+ private static final int LENGTH_OF_AREA_CODE = 3;
+
+ private static boolean isValidLanguage(final String text) {
+ return isAlphabetSequence(text, MIN_LENGTH_OF_LANGUAGE, MAX_LENGTH_OF_LANGUAGE);
+ }
+
+ private static boolean isValidScript(final String text) {
+ return isAlphabetSequence(text, LENGTH_OF_SCRIPT, LENGTH_OF_SCRIPT);
+ }
+
+ private static boolean isValidRegion(final String text) {
+ return isAlphabetSequence(text, MIN_LENGTH_OF_REGION, MAX_LENGTH_OF_REGION)
+ || isDigitSequence(text, LENGTH_OF_AREA_CODE, LENGTH_OF_AREA_CODE);
+ }
+
+ private static boolean isAlphabetSequence(final String text, final int lower, final int upper) {
+ final int length = text.length();
+ if (length < lower || length > upper) {
+ return false;
+ }
+ for (int index = 0; index < length; index++) {
+ if (!isAsciiAlphabet(text.charAt(index))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean isDigitSequence(final String text, final int lower, final int upper) {
+ final int length = text.length();
+ if (length < lower || length > upper) {
+ return false;
+ }
+ for (int index = 0; index < length; ++index) {
+ if (!isAsciiDigit(text.charAt(index))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean isAsciiAlphabet(char c) {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+ }
+
+ private static boolean isAsciiDigit(char c) {
+ return c >= '0' && c <= '9';
+ }
+
+ public static String getLocaleCode(final Locale locale) {
+ if (locale == DEFAULT_LOCALE) {
+ return DEFAULT_LOCALE_CODE;
+ }
+ return locale.toString();
+ }
+
+ public static String getLocaleDisplayName(final Locale locale) {
+ if (locale == DEFAULT_LOCALE) {
+ return DEFAULT_LOCALE_CODE;
+ }
+ if (locale.getLanguage().equals(NO_LANGUAGE_LOCALE_CODE)) {
+ return NO_LANGUAGE_LOCALE_DISPLAY_NAME;
+ }
+ return locale.getDisplayName(Locale.ENGLISH);
+ }
+}
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MakeKeyboardText.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MakeKeyboardText.java
index 36a03f8dc..6c15ce6bf 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MakeKeyboardText.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MakeKeyboardText.java
@@ -36,7 +36,7 @@ public class MakeKeyboardText {
}
public Options(final String[] argsArray) {
- final LinkedList<String> args = new LinkedList<String>(Arrays.asList(argsArray));
+ final LinkedList<String> args = new LinkedList<>(Arrays.asList(argsArray));
String arg = null;
String java = null;
try {
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
index 2643e01ec..563acc57e 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
@@ -16,78 +16,100 @@
package com.android.inputmethod.keyboard.tools;
-import java.io.Closeable;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
+import java.util.TreeMap;
import java.util.jar.JarFile;
public class MoreKeysResources {
private static final String TEXT_RESOURCE_NAME = "donottranslate-more-keys.xml";
- private static final String JAVA_TEMPLATE = "KeyboardTextsSet.tmpl";
+ private static final String JAVA_TEMPLATE = "KeyboardTextsTable.tmpl";
private static final String MARK_NAMES = "@NAMES@";
private static final String MARK_DEFAULT_TEXTS = "@DEFAULT_TEXTS@";
private static final String MARK_TEXTS = "@TEXTS@";
- private static final String MARK_LANGUAGES_AND_TEXTS = "@LANGUAGES_AND_TEXTS@";
- private static final String DEFAUT_LANGUAGE_NAME = "DEFAULT";
- private static final String ARRAY_NAME_FOR_LANGUAGE = "LANGUAGE_%s";
+ private static final String TEXTS_ARRAY_NAME_PREFIX = "TEXTS_";
+ private static final String MARK_LOCALES_AND_TEXTS = "@LOCALES_AND_TEXTS@";
private static final String EMPTY_STRING_VAR = "EMPTY";
- private static final String NO_LANGUAGE_CODE = "zz";
- private static final String NO_LANGUAGE_DISPLAY_NAME = "Alphabet";
-
private final JarFile mJar;
- // Language to string resources map.
- private final HashMap<String, StringResourceMap> mResourcesMap =
- new HashMap<String, StringResourceMap>();
- // Name to id map.
- private final HashMap<String, Integer> mNameToIdMap = new HashMap<String,Integer>();
+ // String resources maps sorted by its language. The language is determined from the jar entry
+ // name by calling {@link JarUtils#getLocaleFromEntryName(String)}.
+ private final TreeMap<String, StringResourceMap> mResourcesMap = new TreeMap<>();
+ // Default string resources map.
+ private final StringResourceMap mDefaultResourceMap;
+ // Histogram of string resource names. This is used to sort {@link #mSortedResourceNames}.
+ private final HashMap<String, Integer> mNameHistogram = new HashMap<>();
+ // Sorted string resource names array; Descending order of histogram count.
+ // The string resource name is specified as an attribute "name" in string resource files.
+ // The string resource can be accessed by specifying name "!text/<name>"
+ // via {@link KeyboardTextsSet#getText(String)}.
+ private final String[] mSortedResourceNames;
public MoreKeysResources(final JarFile jar) {
mJar = jar;
- final ArrayList<String> resources = JarUtils.getNameListing(jar, TEXT_RESOURCE_NAME);
- for (final String name : resources) {
- final String dirName = name.substring(0, name.lastIndexOf('/'));
- final int pos = dirName.lastIndexOf('/');
- final String parentName = (pos >= 0) ? dirName.substring(pos + 1) : dirName;
- final String language = getLanguageFromResDir(parentName);
- final InputStream stream = JarUtils.openResource(name);
- try {
- mResourcesMap.put(language, new StringResourceMap(stream));
- } finally {
- close(stream);
- }
+ final ArrayList<String> resourceEntryNames = JarUtils.getEntryNameListing(
+ jar, TEXT_RESOURCE_NAME);
+ for (final String entryName : resourceEntryNames) {
+ final StringResourceMap resMap = new StringResourceMap(entryName);
+ mResourcesMap.put(LocaleUtils.getLocaleCode(resMap.mLocale), resMap);
}
- }
-
- private static String getLanguageFromResDir(final String dirName) {
- final int languagePos = dirName.indexOf('-');
- if (languagePos < 0) {
- // Default resource.
- return DEFAUT_LANGUAGE_NAME;
+ mDefaultResourceMap = mResourcesMap.get(
+ LocaleUtils.getLocaleCode(LocaleUtils.DEFAULT_LOCALE));
+
+ // Initialize name histogram and names list.
+ final HashMap<String, Integer> nameHistogram = mNameHistogram;
+ final ArrayList<String> resourceNamesList = new ArrayList<>();
+ for (final StringResource res : mDefaultResourceMap.getResources()) {
+ nameHistogram.put(res.mName, 0); // Initialize histogram value.
+ resourceNamesList.add(res.mName);
}
- final String language = dirName.substring(languagePos + 1);
- final int countryPos = language.indexOf("-r");
- if (countryPos < 0) {
- return language;
+ // Make name histogram.
+ for (final String locale : mResourcesMap.keySet()) {
+ final StringResourceMap resMap = mResourcesMap.get(locale);
+ if (resMap == mDefaultResourceMap) continue;
+ for (final StringResource res : resMap.getResources()) {
+ if (!mDefaultResourceMap.contains(res.mName)) {
+ throw new RuntimeException(res.mName + " in " + locale
+ + " doesn't have default resource");
+ }
+ final int histogramValue = nameHistogram.get(res.mName);
+ nameHistogram.put(res.mName, histogramValue + 1);
+ }
}
- return language.replace("-r", "_");
+ // Sort names list.
+ Collections.sort(resourceNamesList, new Comparator<String>() {
+ @Override
+ public int compare(final String leftName, final String rightName) {
+ final int leftCount = nameHistogram.get(leftName);
+ final int rightCount = nameHistogram.get(rightName);
+ // Descending order of histogram count.
+ if (leftCount > rightCount) return -1;
+ if (leftCount < rightCount) return 1;
+ // TODO: Add further criteria to order the same histogram value names to be able to
+ // minimize footprints of string resources arrays.
+ return 0;
+ }
+ });
+ mSortedResourceNames = resourceNamesList.toArray(new String[resourceNamesList.size()]);
}
public void writeToJava(final String outDir) {
- final ArrayList<String> list = JarUtils.getNameListing(mJar, JAVA_TEMPLATE);
- if (list.isEmpty())
+ final ArrayList<String> list = JarUtils.getEntryNameListing(mJar, JAVA_TEMPLATE);
+ if (list.isEmpty()) {
throw new RuntimeException("Can't find java template " + JAVA_TEMPLATE);
- if (list.size() > 1)
+ }
+ if (list.size() > 1) {
throw new RuntimeException("Found multiple java template " + JAVA_TEMPLATE);
+ }
final String template = list.get(0);
final String javaPackage = template.substring(0, template.lastIndexOf('/'));
PrintStream ps = null;
@@ -107,8 +129,8 @@ public class MoreKeysResources {
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
- close(lnr);
- close(ps);
+ JarUtils.close(lnr);
+ JarUtils.close(ps);
}
}
@@ -122,8 +144,8 @@ public class MoreKeysResources {
dumpDefaultTexts(out);
} else if (line.contains(MARK_TEXTS)) {
dumpTexts(out);
- } else if (line.contains(MARK_LANGUAGES_AND_TEXTS)) {
- dumpLanguageMap(out);
+ } else if (line.contains(MARK_LOCALES_AND_TEXTS)) {
+ dumpLocalesMap(out);
} else {
out.println(line);
}
@@ -131,70 +153,62 @@ public class MoreKeysResources {
}
private void dumpNames(final PrintStream out) {
- final StringResourceMap defaultResMap = mResourcesMap.get(DEFAUT_LANGUAGE_NAME);
- int id = 0;
- for (final StringResource res : defaultResMap.getResources()) {
- out.format(" /* %2d */ \"%s\",\n", id, res.mName);
- mNameToIdMap.put(res.mName, id);
- id++;
+ final int namesCount = mSortedResourceNames.length;
+ for (int index = 0; index < namesCount; index++) {
+ final String name = mSortedResourceNames[index];
+ final int histogramValue = mNameHistogram.get(name);
+ out.format(" /* %3d:%2d */ \"%s\",\n", index, histogramValue, name);
}
}
private void dumpDefaultTexts(final PrintStream out) {
- final StringResourceMap defaultResMap = mResourcesMap.get(DEFAUT_LANGUAGE_NAME);
- dumpTextsInternal(out, defaultResMap, defaultResMap);
+ final int outputArraySize = dumpTextsInternal(out, mDefaultResourceMap);
+ mDefaultResourceMap.setOutputArraySize(outputArraySize);
}
- private void dumpTexts(final PrintStream out) {
- final StringResourceMap defaultResMap = mResourcesMap.get(DEFAUT_LANGUAGE_NAME);
- final ArrayList<String> allLanguages = new ArrayList<String>();
- allLanguages.addAll(mResourcesMap.keySet());
- Collections.sort(allLanguages);
- for (final String language : allLanguages) {
- if (language.equals(DEFAUT_LANGUAGE_NAME)) {
- continue;
- }
- out.format(" /* Language %s: %s */\n", language, getLanguageDisplayName(language));
- out.format(" private static final String[] " + ARRAY_NAME_FOR_LANGUAGE + " = {\n",
- language);
- final StringResourceMap resMap = mResourcesMap.get(language);
- for (final StringResource res : resMap.getResources()) {
- if (!defaultResMap.contains(res.mName)) {
- throw new RuntimeException(res.mName + " in " + language
- + " doesn't have default resource");
- }
- }
- dumpTextsInternal(out, resMap, defaultResMap);
- out.format(" };\n\n");
- }
+ private static String getArrayNameForLocale(final Locale locale) {
+ return TEXTS_ARRAY_NAME_PREFIX + LocaleUtils.getLocaleCode(locale);
}
- private void dumpLanguageMap(final PrintStream out) {
- final ArrayList<String> allLanguages = new ArrayList<String>();
- allLanguages.addAll(mResourcesMap.keySet());
- Collections.sort(allLanguages);
- for (final String language : allLanguages) {
- out.format(" \"%s\", " + ARRAY_NAME_FOR_LANGUAGE + ", /* %s */\n",
- language, language, getLanguageDisplayName(language));
+ private void dumpTexts(final PrintStream out) {
+ for (final StringResourceMap resMap : mResourcesMap.values()) {
+ final Locale locale = resMap.mLocale;
+ if (resMap == mDefaultResourceMap) continue;
+ out.format(" /* Locale %s: %s */\n",
+ locale, LocaleUtils.getLocaleDisplayName(locale));
+ out.format(" private static final String[] " + getArrayNameForLocale(locale)
+ + " = {\n");
+ final int outputArraySize = dumpTextsInternal(out, resMap);
+ resMap.setOutputArraySize(outputArraySize);
+ out.format(" };\n\n");
}
}
- private static String getLanguageDisplayName(final String language) {
- if (language.equals(NO_LANGUAGE_CODE)) {
- return NO_LANGUAGE_DISPLAY_NAME;
- } else {
- return new Locale(language).getDisplayLanguage();
+ private void dumpLocalesMap(final PrintStream out) {
+ for (final StringResourceMap resMap : mResourcesMap.values()) {
+ final Locale locale = resMap.mLocale;
+ final String localeStr = LocaleUtils.getLocaleCode(locale);
+ final String localeToDump = (locale == LocaleUtils.DEFAULT_LOCALE)
+ ? String.format("\"%s\"", localeStr)
+ : String.format("\"%s\"%s", localeStr, " ".substring(localeStr.length()));
+ out.format(" %s, %-12s /* %3d/%3d %s */\n",
+ localeToDump, getArrayNameForLocale(locale) + ",",
+ resMap.getResources().size(), resMap.getOutputArraySize(),
+ LocaleUtils.getLocaleDisplayName(locale));
}
}
- private static void dumpTextsInternal(final PrintStream out, final StringResourceMap resMap,
- final StringResourceMap defaultResMap) {
+ private int dumpTextsInternal(final PrintStream out, final StringResourceMap resMap) {
final ArrayInitializerFormatter formatter =
- new ArrayInitializerFormatter(out, 100, " ");
+ new ArrayInitializerFormatter(out, 100, " ", mSortedResourceNames);
+ int outputArraySize = 0;
boolean successiveNull = false;
- for (final StringResource defaultRes : defaultResMap.getResources()) {
- if (resMap.contains(defaultRes.mName)) {
- final StringResource res = resMap.get(defaultRes.mName);
+ final int namesCount = mSortedResourceNames.length;
+ for (int index = 0; index < namesCount; index++) {
+ final String name = mSortedResourceNames[index];
+ final StringResource res = resMap.get(name);
+ if (res != null) {
+ // TODO: Check whether the resource value is equal to the default.
if (res.mComment != null) {
formatter.outCommentLines(addPrefix(" // ", res. mComment));
}
@@ -205,6 +219,7 @@ public class MoreKeysResources {
formatter.outElement(String.format("\"%s\",", escaped));
}
successiveNull = false;
+ outputArraySize = formatter.getCurrentIndex();
} else {
formatter.outElement("null,");
successiveNull = true;
@@ -213,6 +228,7 @@ public class MoreKeysResources {
if (!successiveNull) {
formatter.flush();
}
+ return outputArraySize;
}
private static String addPrefix(final String prefix, final String lines) {
@@ -234,31 +250,6 @@ public class MoreKeysResources {
sb.append(String.format("\\u%04X", (int)c));
}
}
- return replaceIncompatibleEscape(sb.toString());
- }
-
- private static String replaceIncompatibleEscape(final String text) {
- String t = text;
- t = replaceAll(t, "\\?", "?");
- t = replaceAll(t, "\\@", "@");
- t = replaceAll(t, "@string/", "!text/");
- return t;
- }
-
- private static String replaceAll(final String text, final String target, final String replace) {
- String t = text;
- while (t.indexOf(target) >= 0) {
- t = t.replace(target, replace);
- }
- return t;
- }
-
- private static void close(Closeable stream) {
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException e) {
- }
+ return sb.toString();
}
}
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java
index cc7ff6a9c..cf44f2cad 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
@@ -34,31 +35,45 @@ import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class StringResourceMap {
+ // Locale of this string resource map.
+ public final Locale mLocale;
// String resource list.
private final List<StringResource> mResources;
// Name to string resource map.
private final Map<String, StringResource> mResourcesMap;
- public StringResourceMap(final InputStream is) {
+ // The length of String[] that is created from this {@link StringResourceMap}. The length is
+ // calculated in {@link MoreKeysResources#dumpTexts(OutputStream)} and recorded by
+ // {@link #setOutputArraySize(int)}. The recorded length is used as a part of comment by
+ // {@link MoreKeysResources#dumpLocaleMap(OutputStream)} via {@link #getOutputArraySize()}.
+ private int mOutputArraySize;
+
+ public StringResourceMap(final String jarEntryName) {
+ mLocale = JarUtils.getLocaleFromEntryName(jarEntryName);
final StringResourceHandler handler = new StringResourceHandler();
final SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
+ final InputStream stream = JarUtils.openResource(jarEntryName);
try {
final SAXParser parser = factory.newSAXParser();
// In order to get comment tag.
parser.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
- parser.parse(is, handler);
+ parser.parse(stream, handler);
} catch (ParserConfigurationException e) {
+ throw new RuntimeException(e.getMessage(), e);
} catch (SAXParseException e) {
throw new RuntimeException(e.getMessage() + " at line " + e.getLineNumber()
- + ", column " + e.getColumnNumber());
+ + ", column " + e.getColumnNumber(), e);
} catch (SAXException e) {
- throw new RuntimeException(e.getMessage());
+ throw new RuntimeException(e.getMessage(), e);
} catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ } finally {
+ JarUtils.close(stream);
}
mResources = Collections.unmodifiableList(handler.mResources);
- final HashMap<String,StringResource> map = new HashMap<String,StringResource>();
+ final HashMap<String, StringResource> map = new HashMap<>();
for (final StringResource res : mResources) {
map.put(res.mName, res);
}
@@ -77,12 +92,20 @@ public class StringResourceMap {
return mResourcesMap.get(name);
}
+ public void setOutputArraySize(final int arraySize) {
+ mOutputArraySize = arraySize;
+ }
+
+ public int getOutputArraySize() {
+ return mOutputArraySize;
+ }
+
static class StringResourceHandler extends DefaultHandler2 {
private static final String TAG_RESOURCES = "resources";
private static final String TAG_STRING = "string";
private static final String ATTR_NAME = "name";
- final ArrayList<StringResource> mResources = new ArrayList<StringResource>();
+ final ArrayList<StringResource> mResources = new ArrayList<>();
private String mName;
private final StringBuilder mValue = new StringBuilder();