Create methods in LatinIME to make the current dict lists

Bug: 7005813
Change-Id: I82232af8e3071333b6fd01e4453b6b3c0a3ddb1f
main
Jean Chalard 2013-01-29 16:34:14 +09:00
parent 3d0477fbd2
commit af4a7e8c4b
5 changed files with 118 additions and 14 deletions

View File

@ -76,7 +76,7 @@ final class BinaryDictionaryGetter {
/** /**
* Returns a file address from a resource, or null if it cannot be opened. * Returns a file address from a resource, or null if it cannot be opened.
*/ */
private static AssetFileAddress loadFallbackResource(final Context context, public static AssetFileAddress loadFallbackResource(final Context context,
final int fallbackResId) { final int fallbackResId) {
final AssetFileDescriptor afd = context.getResources().openRawResourceFd(fallbackResId); final AssetFileDescriptor afd = context.getResources().openRawResourceFd(fallbackResId);
if (afd == null) { if (afd == null) {
@ -149,7 +149,7 @@ final class BinaryDictionaryGetter {
* @param context the context on which to open the files upon. * @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. * @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) { public static File[] getCachedWordLists(final String locale, final Context context) {
final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context); final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context);
if (null == directoryList) return EMPTY_FILE_ARRAY; if (null == directoryList) return EMPTY_FILE_ARRAY;
final HashMap<String, FileAndMatchLevel> cacheFiles = CollectionUtils.newHashMap(); final HashMap<String, FileAndMatchLevel> cacheFiles = CollectionUtils.newHashMap();

View File

@ -17,6 +17,7 @@
package com.android.inputmethod.latin; package com.android.inputmethod.latin;
import android.content.Context; import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources; import android.content.res.Resources;
import android.util.Log; import android.util.Log;
@ -26,6 +27,7 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
/** /**
@ -41,6 +43,18 @@ public class DictionaryInfoUtils {
// 6 digits - unicode is limited to 21 bits // 6 digits - unicode is limited to 21 bits
private static final int MAX_HEX_DIGITS_FOR_CODEPOINT = 6; private static final int MAX_HEX_DIGITS_FOR_CODEPOINT = 6;
public static class DictionaryInfo {
public final Locale mLocale;
public final AssetFileAddress mFileAddress;
public final int mVersion;
public DictionaryInfo(final Locale locale, final AssetFileAddress fileAddress,
final int version) {
mLocale = locale;
mFileAddress = fileAddress;
mVersion = version;
}
}
private DictionaryInfoUtils() { private DictionaryInfoUtils() {
// Private constructor to forbid instantation of this helper class. // Private constructor to forbid instantation of this helper class.
} }
@ -234,12 +248,79 @@ public class DictionaryInfoUtils {
public static FileHeader getDictionaryFileHeaderOrNull(final File file) { public static FileHeader getDictionaryFileHeaderOrNull(final File file) {
try { try {
final FileHeader header = BinaryDictIOUtils.getDictionaryFileHeader(file); return BinaryDictIOUtils.getDictionaryFileHeader(file, 0, file.length());
return header;
} catch (UnsupportedFormatException e) { } catch (UnsupportedFormatException e) {
return null; return null;
} catch (IOException e) { } catch (IOException e) {
return null; return null;
} }
} }
private static DictionaryInfo createDictionaryInfoFromFileAddress(
final AssetFileAddress fileAddress) {
final FileHeader header = BinaryDictIOUtils.getDictionaryFileHeaderOrNull(
new File(fileAddress.mFilename), fileAddress.mOffset, fileAddress.mLength);
final Locale locale = LocaleUtils.constructLocaleFromString(header.getLocaleString());
final String version = header.getVersion();
return new DictionaryInfo(locale, fileAddress, Integer.parseInt(version));
}
private static void addOrUpdateDictInfo(final ArrayList<DictionaryInfo> dictList,
final DictionaryInfo newElement) {
for (final DictionaryInfo info : dictList) {
if (info.mLocale.equals(newElement.mLocale)) {
if (newElement.mVersion <= info.mVersion) {
return;
}
dictList.remove(info);
}
}
dictList.add(newElement);
}
public static ArrayList<DictionaryInfo> getCurrentDictionaryFileNameAndVersionInfo(
final Context context) {
final ArrayList<DictionaryInfo> dictList = CollectionUtils.newArrayList();
// Retrieve downloaded dictionaries
final File[] directoryList = getCachedDirectoryList(context);
for (final File directory : directoryList) {
final String localeString = getWordListIdFromFileName(directory.getName());
File[] dicts = BinaryDictionaryGetter.getCachedWordLists(localeString, context);
for (final File dict : dicts) {
final String wordListId = getWordListIdFromFileName(dict.getName());
if (!DictionaryInfoUtils.isMainWordListId(wordListId)) continue;
final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
final AssetFileAddress fileAddress = AssetFileAddress.makeFromFile(dict);
final DictionaryInfo dictionaryInfo =
createDictionaryInfoFromFileAddress(fileAddress);
// Protect against cases of a less-specific dictionary being found, like an
// en dictionary being used for an en_US locale. In this case, the en dictionary
// should be used for en_US but discounted for listing purposes.
if (!dictionaryInfo.mLocale.equals(locale)) continue;
addOrUpdateDictInfo(dictList, dictionaryInfo);
}
}
// Retrieve files from assets
final Resources resources = context.getResources();
final AssetManager assets = resources.getAssets();
for (final String localeString : assets.getLocales()) {
final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
final int resourceId =
DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale(
context.getResources(), locale);
if (0 == resourceId) continue;
final AssetFileAddress fileAddress =
BinaryDictionaryGetter.loadFallbackResource(context, resourceId);
final DictionaryInfo dictionaryInfo = createDictionaryInfoFromFileAddress(fileAddress);
// Protect against cases of a less-specific dictionary being found, like an
// en dictionary being used for an en_US locale. In this case, the en dictionary
// should be used for en_US but discounted for listing purposes.
if (!dictionaryInfo.mLocale.equals(locale)) continue;
addOrUpdateDictInfo(dictList, dictionaryInfo);
}
return dictList;
}
} }

View File

@ -39,7 +39,6 @@ import java.util.Locale;
public class ExternalDictionaryGetterForDebug { public class ExternalDictionaryGetterForDebug {
private static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath() private static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath()
+ "/Download"; + "/Download";
private static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale";
private static String[] findDictionariesInTheDownloadedFolder() { private static String[] findDictionariesInTheDownloadedFolder() {
final File[] files = new File(SOURCE_FOLDER).listFiles(); final File[] files = new File(SOURCE_FOLDER).listFiles();
@ -90,8 +89,7 @@ public class ExternalDictionaryGetterForDebug {
final File file = new File(SOURCE_FOLDER, fileName.toString()); final File file = new File(SOURCE_FOLDER, fileName.toString());
final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file); final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file);
final StringBuilder message = new StringBuilder(); final StringBuilder message = new StringBuilder();
final String locale = final String locale = header.getLocaleString();
header.mDictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_ATTRIBUTE);
for (String key : header.mDictionaryOptions.mAttributes.keySet()) { for (String key : header.mDictionaryOptions.mAttributes.keySet()) {
message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key)); message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key));
message.append("\n"); message.append("\n");
@ -123,13 +121,11 @@ public class ExternalDictionaryGetterForDebug {
BufferedOutputStream outputStream = null; BufferedOutputStream outputStream = null;
File tempFile = null; File tempFile = null;
try { try {
final String locale = final String locale = header.getLocaleString();
header.mDictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_ATTRIBUTE);
// Create the id for a main dictionary for this locale // Create the id for a main dictionary for this locale
final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY
+ BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale; + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale;
final String finalFileName = final String finalFileName = DictionaryInfoUtils.getCacheFileName(id, locale, context);
DictionaryInfoUtils.getCacheFileName(id, locale, context);
final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context); final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
tempFile = new File(tempFileName); tempFile = new File(tempFileName);
tempFile.delete(); tempFile.delete();

View File

@ -988,20 +988,35 @@ public final class BinaryDictIOUtils {
* This is quite resource intensive - don't call when performance is critical. * This is quite resource intensive - don't call when performance is critical.
* *
* @param file The file to read. * @param file The file to read.
* @param offset The offset in the file where to start reading the data.
* @param length The length of the data file.
*/ */
private static final int HEADER_READING_BUFFER_SIZE = 16384; private static final int HEADER_READING_BUFFER_SIZE = 16384;
public static FileHeader getDictionaryFileHeader(final File file) public static FileHeader getDictionaryFileHeader(
throws FileNotFoundException, IOException, UnsupportedFormatException { final File file, final long offset, final long length)
throws FileNotFoundException, IOException, UnsupportedFormatException {
final byte[] buffer = new byte[HEADER_READING_BUFFER_SIZE]; final byte[] buffer = new byte[HEADER_READING_BUFFER_SIZE];
final FileInputStream inStream = new FileInputStream(file); final FileInputStream inStream = new FileInputStream(file);
try { try {
inStream.read(buffer); inStream.read(buffer);
final BinaryDictInputOutput.ByteBufferWrapper wrapper = final BinaryDictInputOutput.ByteBufferWrapper wrapper =
new BinaryDictInputOutput.ByteBufferWrapper(inStream.getChannel().map( new BinaryDictInputOutput.ByteBufferWrapper(inStream.getChannel().map(
FileChannel.MapMode.READ_ONLY, 0, file.length())); FileChannel.MapMode.READ_ONLY, offset, length));
return BinaryDictInputOutput.readHeader(wrapper); return BinaryDictInputOutput.readHeader(wrapper);
} finally { } finally {
inStream.close(); inStream.close();
} }
} }
public static FileHeader getDictionaryFileHeaderOrNull(final File file, final long offset,
final long length) {
try {
final FileHeader header = getDictionaryFileHeader(file, offset, length);
return header;
} catch (UnsupportedFormatException e) {
return null;
} catch (IOException e) {
return null;
}
}
} }

View File

@ -256,12 +256,24 @@ public final class FormatSpec {
public final int mHeaderSize; public final int mHeaderSize;
public final DictionaryOptions mDictionaryOptions; public final DictionaryOptions mDictionaryOptions;
public final FormatOptions mFormatOptions; public final FormatOptions mFormatOptions;
private static final String DICTIONARY_VERSION_ATTRIBUTE = "version";
private static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale";
public FileHeader(final int headerSize, final DictionaryOptions dictionaryOptions, public FileHeader(final int headerSize, final DictionaryOptions dictionaryOptions,
final FormatOptions formatOptions) { final FormatOptions formatOptions) {
mHeaderSize = headerSize; mHeaderSize = headerSize;
mDictionaryOptions = dictionaryOptions; mDictionaryOptions = dictionaryOptions;
mFormatOptions = formatOptions; mFormatOptions = formatOptions;
} }
// Helper method to get the locale as a String
public String getLocaleString() {
return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_LOCALE_ATTRIBUTE);
}
// Helper method to get the version String
public String getVersion() {
return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_VERSION_ATTRIBUTE);
}
} }
private FormatSpec() { private FormatSpec() {