diff options
author | 2013-01-29 10:29:25 +0000 | |
---|---|---|
committer | 2013-01-29 10:29:25 +0000 | |
commit | 3d0477fbd2b9b79fe3e8fdc9de2a8776fe76be78 (patch) | |
tree | 73b121a13a633cf4a0dfa7165f1df62fb2e32c9b /java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java | |
parent | 306c7fb9b7d6fc4db91151c4dcfa3b3e07a3d28f (diff) | |
parent | d515f134f726c432c0bab5600e7b31ed989fb1b5 (diff) | |
download | latinime-3d0477fbd2b9b79fe3e8fdc9de2a8776fe76be78.tar.gz latinime-3d0477fbd2b9b79fe3e8fdc9de2a8776fe76be78.tar.xz latinime-3d0477fbd2b9b79fe3e8fdc9de2a8776fe76be78.zip |
Merge "Refactoring"
Diffstat (limited to 'java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java | 169 |
1 files changed, 15 insertions, 154 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index 22b5cd55c..5da0f1be8 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -66,109 +66,11 @@ final class BinaryDictionaryGetter { private BinaryDictionaryGetter() {} /** - * Returns whether we may want to use this character as part of a file name. - * - * This basically only accepts ascii letters and numbers, and rejects everything else. - */ - private static boolean isFileNameCharacter(int codePoint) { - if (codePoint >= 0x30 && codePoint <= 0x39) return true; // Digit - if (codePoint >= 0x41 && codePoint <= 0x5A) return true; // Uppercase - if (codePoint >= 0x61 && codePoint <= 0x7A) return true; // Lowercase - return codePoint == '_'; // Underscore - } - - /** - * Escapes a string for any characters that may be suspicious for a file or directory name. - * - * Concretely this does a sort of URL-encoding except it will encode everything that's not - * alphanumeric or underscore. (true URL-encoding leaves alone characters like '*', which - * we cannot allow here) - */ - // TODO: create a unit test for this method - private static String replaceFileNameDangerousCharacters(final String name) { - // This assumes '%' is fully available as a non-separator, normal - // character in a file name. This is probably true for all file systems. - final StringBuilder sb = new StringBuilder(); - final int nameLength = name.length(); - for (int i = 0; i < nameLength; i = name.offsetByCodePoints(i, 1)) { - final int codePoint = name.codePointAt(i); - if (isFileNameCharacter(codePoint)) { - sb.appendCodePoint(codePoint); - } else { - // 6 digits - unicode is limited to 21 bits - sb.append(String.format((Locale)null, "%%%1$06x", codePoint)); - } - } - return sb.toString(); - } - - /** - * Reverse escaping done by replaceFileNameDangerousCharacters. - */ - private static String getWordListIdFromFileName(final String fname) { - final StringBuilder sb = new StringBuilder(); - final int fnameLength = fname.length(); - for (int i = 0; i < fnameLength; i = fname.offsetByCodePoints(i, 1)) { - final int codePoint = fname.codePointAt(i); - if ('%' != codePoint) { - sb.appendCodePoint(codePoint); - } else { - final int encodedCodePoint = Integer.parseInt(fname.substring(i + 1, i + 7), 16); - i += 6; - sb.appendCodePoint(encodedCodePoint); - } - } - return sb.toString(); - } - - /** - * Helper method to get the top level cache directory. - */ - private static String getWordListCacheDirectory(final Context context) { - return context.getFilesDir() + File.separator + "dicts"; - } - - /** - * Find out the cache directory associated with a specific locale. - */ - private static String getCacheDirectoryForLocale(final String locale, final Context context) { - final String relativeDirectoryName = replaceFileNameDangerousCharacters(locale); - final String absoluteDirectoryName = getWordListCacheDirectory(context) + File.separator - + relativeDirectoryName; - final File directory = new File(absoluteDirectoryName); - if (!directory.exists()) { - if (!directory.mkdirs()) { - Log.e(TAG, "Could not create the directory for locale" + locale); - } - } - return absoluteDirectoryName; - } - - /** - * Generates a file name for the id and locale passed as an argument. - * - * In the current implementation the file name returned will always be unique for - * any id/locale pair, but please do not expect that the id can be the same for - * different dictionaries with different locales. An id should be unique for any - * dictionary. - * The file name is pretty much an URL-encoded version of the id inside a directory - * named like the locale, except it will also escape characters that look dangerous - * to some file systems. - * @param id the id of the dictionary for which to get a file name - * @param locale the locale for which to get the file name as a string - * @param context the context to use for getting the directory - * @return the name of the file to be created - */ - public static String getCacheFileName(String id, String locale, Context context) { - final String fileName = replaceFileNameDangerousCharacters(id); - return getCacheDirectoryForLocale(locale, context) + File.separator + fileName; - } - - /** * Generates a unique temporary file name in the app cache directory. */ public static String getTempFileName(String id, Context context) throws IOException { - return File.createTempFile(replaceFileNameDangerousCharacters(id), null).getAbsolutePath(); + return File.createTempFile(DictionaryInfoUtils.replaceFileNameDangerousCharacters(id), + null).getAbsolutePath(); } /** @@ -222,27 +124,6 @@ final class BinaryDictionaryGetter { } /** - * Helper method to the list of cache directories, one for each distinct locale. - */ - private static File[] getCachedDirectoryList(final Context context) { - return new File(getWordListCacheDirectory(context)).listFiles(); - } - - /** - * Returns the category for a given file name. - * - * This parses the file name, extracts the category, and returns it. See - * {@link #getMainDictId(Locale)} and {@link #isMainWordListId(String)}. - * @return The category as a string or null if it can't be found in the file name. - */ - private static String getCategoryFromFileName(final String fileName) { - final String id = getWordListIdFromFileName(fileName); - final String[] idArray = id.split(ID_CATEGORY_SEPARATOR); - if (2 != idArray.length) return null; - return idArray[0]; - } - - /** * Utility class for the {@link #getCachedWordLists} method */ private static final class FileAndMatchLevel { @@ -268,20 +149,21 @@ final class BinaryDictionaryGetter { * @param context the context on which to open the files upon. * @return an array of binary dictionary files, which may be empty but may not be null. */ - private static File[] getCachedWordLists(final String locale, - final Context context) { - final File[] directoryList = getCachedDirectoryList(context); + private static File[] getCachedWordLists(final String locale, final Context context) { + final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context); if (null == directoryList) return EMPTY_FILE_ARRAY; final HashMap<String, FileAndMatchLevel> cacheFiles = CollectionUtils.newHashMap(); for (File directory : directoryList) { if (!directory.isDirectory()) continue; - final String dirLocale = getWordListIdFromFileName(directory.getName()); + final String dirLocale = + DictionaryInfoUtils.getWordListIdFromFileName(directory.getName()); final int matchLevel = LocaleUtils.getMatchLevel(dirLocale, locale); if (LocaleUtils.isMatch(matchLevel)) { final File[] wordLists = directory.listFiles(); if (null != wordLists) { for (File wordList : wordLists) { - final String category = getCategoryFromFileName(wordList.getName()); + final String category = + DictionaryInfoUtils.getCategoryFromFileName(wordList.getName()); final FileAndMatchLevel currentBestMatch = cacheFiles.get(category); if (null == currentBestMatch || currentBestMatch.mMatchLevel < matchLevel) { cacheFiles.put(category, new FileAndMatchLevel(wordList, matchLevel)); @@ -310,7 +192,7 @@ final class BinaryDictionaryGetter { final File fileToKeep) { try { final File canonicalFileToKeep = fileToKeep.getCanonicalFile(); - final File[] directoryList = getCachedDirectoryList(context); + final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context); if (null == directoryList) return; for (File directory : directoryList) { // There is one directory per locale. See #getCachedDirectoryList @@ -318,7 +200,8 @@ final class BinaryDictionaryGetter { final File[] wordLists = directory.listFiles(); if (null == wordLists) continue; for (File wordList : wordLists) { - final String fileId = getWordListIdFromFileName(wordList.getName()); + final String fileId = + DictionaryInfoUtils.getWordListIdFromFileName(wordList.getName()); if (fileId.equals(id)) { if (!canonicalFileToKeep.equals(wordList.getCanonicalFile())) { wordList.delete(); @@ -331,28 +214,6 @@ final class BinaryDictionaryGetter { } } - - /** - * Returns the id associated with the main word list for a specified locale. - * - * Word lists stored in Android Keyboard's resources are referred to as the "main" - * word lists. Since they can be updated like any other list, we need to assign a - * unique ID to them. This ID is just the name of the language (locale-wise) they - * are for, and this method returns this ID. - */ - private static String getMainDictId(final Locale locale) { - // This works because we don't include by default different dictionaries for - // different countries. This actually needs to return the id that we would - // like to use for word lists included in resources, and the following is okay. - return MAIN_DICTIONARY_CATEGORY + ID_CATEGORY_SEPARATOR + locale.getLanguage().toString(); - } - - private static boolean isMainWordListId(final String id) { - final String[] idArray = id.split(ID_CATEGORY_SEPARATOR); - if (2 != idArray.length) return false; - return MAIN_DICTIONARY_CATEGORY.equals(idArray[0]); - } - // ## HACK ## we prevent usage of a dictionary before version 18 for English only. The reason // for this is, since those do not include whitelist entries, the new code with an old version // of the dictionary would lose whitelist functionality. @@ -429,16 +290,16 @@ final class BinaryDictionaryGetter { hasDefaultWordList); } final File[] cachedWordLists = getCachedWordLists(locale.toString(), context); - final String mainDictId = getMainDictId(locale); + final String mainDictId = DictionaryInfoUtils.getMainDictId(locale); final DictPackSettings dictPackSettings = new DictPackSettings(context); boolean foundMainDict = false; final ArrayList<AssetFileAddress> fileList = CollectionUtils.newArrayList(); // cachedWordLists may not be null, see doc for getCachedDictionaryList for (final File f : cachedWordLists) { - final String wordListId = getWordListIdFromFileName(f.getName()); + final String wordListId = DictionaryInfoUtils.getWordListIdFromFileName(f.getName()); final boolean canUse = f.canRead() && hackCanUseDictionaryFile(locale, f); - if (canUse && isMainWordListId(wordListId)) { + if (canUse && DictionaryInfoUtils.isMainWordListId(wordListId)) { foundMainDict = true; } if (!dictPackSettings.isWordListActive(wordListId)) continue; @@ -451,7 +312,7 @@ final class BinaryDictionaryGetter { if (!foundMainDict && dictPackSettings.isWordListActive(mainDictId)) { final int fallbackResId = - DictionaryFactory.getMainDictionaryResourceId(context.getResources(), locale); + DictionaryInfoUtils.getMainDictionaryResourceId(context.getResources(), locale); final AssetFileAddress fallbackAsset = loadFallbackResource(context, fallbackResId); if (null != fallbackAsset) { fileList.add(fallbackAsset); |