From 222581b90556e065e4c9efcb819101b333f9b863 Mon Sep 17 00:00:00 2001 From: Thad Hughes Date: Wed, 13 Oct 2010 10:17:29 -0700 Subject: [PATCH] go --- AndroidManifest.xml | 1 - res/xml/preferences.xml | 16 -- .../hughes/android/dictionary/Dictionary.java | 240 ------------------ .../dictionary/DictionaryActivity.java | 63 +++-- .../dictionary/DictionaryActivityTest.java | 138 ---------- .../android/dictionary/DownloadActivity.java | 1 + src/com/hughes/android/dictionary/Entry.java | 22 -- .../dictionary/NoDictionaryActivity.java | 62 ----- .../android/dictionary/SimpleEntry.java | 214 ---------------- .../android/dictionary/engine/Dictionary.java | 31 ++- 10 files changed, 54 insertions(+), 734 deletions(-) delete mode 100755 src/com/hughes/android/dictionary/Dictionary.java delete mode 100755 src/com/hughes/android/dictionary/DictionaryActivityTest.java delete mode 100644 src/com/hughes/android/dictionary/Entry.java delete mode 100755 src/com/hughes/android/dictionary/NoDictionaryActivity.java delete mode 100755 src/com/hughes/android/dictionary/SimpleEntry.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 17f77d0..c688901 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -33,7 +33,6 @@ - diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 91784be..7cf7652 100755 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -24,20 +24,4 @@ android:persistent="true" /> - - - - \ No newline at end of file diff --git a/src/com/hughes/android/dictionary/Dictionary.java b/src/com/hughes/android/dictionary/Dictionary.java deleted file mode 100755 index 5de8d32..0000000 --- a/src/com/hughes/android/dictionary/Dictionary.java +++ /dev/null @@ -1,240 +0,0 @@ -package com.hughes.android.dictionary; - -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import com.hughes.android.dictionary.engine.Language; -import com.hughes.util.CachingList; -import com.hughes.util.raf.RAFList; -import com.hughes.util.raf.RAFFactory; -import com.hughes.util.raf.RAFSerializable; -import com.hughes.util.raf.RAFSerializableSerializer; -import com.hughes.util.raf.RAFSerializer; -import com.hughes.util.raf.UniformRAFList; - -public final class Dictionary implements RAFSerializable { - - private static final String VERSION_CODE = "DictionaryVersion=2.0"; - - static final RAFSerializer ENTRY_SERIALIZER = null; - static final RAFSerializer ROW_SERIALIZER = new RAFSerializableSerializer( - Row.RAF_FACTORY); - static final RAFSerializer INDEX_ENTRY_SERIALIZER = new RAFSerializableSerializer( - IndexEntry.RAF_FACTORY); - - final String dictionaryInfo; - final List sources; - final List entries; - final LanguageData[] languageDatas = new LanguageData[2]; - - public Dictionary(final String dictionaryInfo, final Language language0, final Language language1) { - this.dictionaryInfo = dictionaryInfo; - sources = new ArrayList(); - languageDatas[0] = new LanguageData(this, language0, SimpleEntry.LANG1); - languageDatas[1] = new LanguageData(this, language1, SimpleEntry.LANG2); - entries = new ArrayList(); - } - - public Dictionary(final RandomAccessFile raf) throws IOException { - dictionaryInfo = raf.readUTF(); - sources = new ArrayList(RAFList.create(raf, RAFSerializer.STRING, raf.getFilePointer())); - entries = null; - languageDatas[0] = new LanguageData(this, raf, SimpleEntry.LANG1); - languageDatas[1] = new LanguageData(this, raf, SimpleEntry.LANG2); - final String version = raf.readUTF(); - if (!VERSION_CODE.equals(version)) { - throw new IOException("Invalid dictionary version, found " + version + ", expected: " + VERSION_CODE); - } - } - - public void write(RandomAccessFile raf) throws IOException { - raf.writeUTF(dictionaryInfo); - RAFList.write(raf, sources, RAFSerializer.STRING); - //RAFList.write(raf, entries, ENTRY_SERIALIZER); - languageDatas[0].write(raf); - languageDatas[1].write(raf); - raf.writeUTF(VERSION_CODE); - } - - final class LanguageData implements RAFSerializable { - final Dictionary dictionary; - final Language language; - final byte lang; - final List rows; - final List sortedIndex; - - LanguageData(final Dictionary dictionary, final Language language, final byte lang) { - this.dictionary = dictionary; - this.language = language; - this.lang = lang; - rows = new ArrayList(); - sortedIndex = new ArrayList(); - } - - LanguageData(final Dictionary dictionary, final RandomAccessFile raf, final byte lang) throws IOException { - this.dictionary = dictionary; - language = Language.lookup(raf.readUTF()); - if (language == null) { - throw new RuntimeException("Unknown language."); - } - this.lang = lang; - rows = CachingList.create(UniformRAFList.create(raf, ROW_SERIALIZER, raf - .getFilePointer()), 10000); - sortedIndex = CachingList.create(RAFList.create(raf, - INDEX_ENTRY_SERIALIZER, raf.getFilePointer()), 10000); - } - - public void write(final RandomAccessFile raf) throws IOException { - raf.writeUTF(language.symbol); - UniformRAFList.write(raf, rows, ROW_SERIALIZER, 4); - RAFList.write(raf, sortedIndex, INDEX_ENTRY_SERIALIZER); - } - - String rowToString(final Row row, final boolean onlyFirstSubentry) { - return null; - //return row.isToken() ? sortedIndex.get(row.getIndex()).word : entries - // .get(row.getIndex()).getRawText(onlyFirstSubentry); - } - - int lookup(String word, final AtomicBoolean interrupted) { - word = word.toLowerCase(); - - int start = 0; - int end = sortedIndex.size(); - while (start < end) { - final int mid = (start + end) / 2; - if (interrupted.get()) { - return mid; - } - final IndexEntry midEntry = sortedIndex.get(mid); - if (midEntry.word.equals("pre-print")) { - System.out.println(); - } - - final int comp = language.sortComparator.compare(word, midEntry.word.toLowerCase()); - if (comp == 0) { - int result = mid; - while (result > 0 && language.findComparator.compare(word, sortedIndex.get(result - 1).word.toLowerCase()) == 0) { - --result; - if (interrupted.get()) { - return result; - } - } - return result; - } else if (comp < 0) { -// Log.d("THAD", "Upper bound: " + midEntry); - end = mid; - } else { -// Log.d("THAD", "Lower bound: " + midEntry); - start = mid + 1; - } - } - return Math.min(sortedIndex.size() - 1, start); - } - - public int getPrevTokenRow(final int rowIndex) { - final IndexEntry indexEntry = getIndexEntryForRow(rowIndex); - final Row tokenRow = rows.get(indexEntry.startRow); - assert tokenRow.isToken(); - final int prevTokenIndex = tokenRow.getIndex() - 1; - if (indexEntry.startRow == rowIndex && prevTokenIndex >= 0) { - return sortedIndex.get(prevTokenIndex).startRow; - } - return indexEntry.startRow; - } - - public int getNextTokenRow(final int rowIndex) { - final IndexEntry indexEntry = getIndexEntryForRow(rowIndex); - final Row tokenRow = rows.get(indexEntry.startRow); - assert tokenRow.isToken(); - final int nextTokenIndex = tokenRow.getIndex() + 1; - if (nextTokenIndex < sortedIndex.size()) { - return sortedIndex.get(nextTokenIndex).startRow; - } - return rows.size() - 1; - } - - public IndexEntry getIndexEntryForRow(final int rowIndex) { - // TODO: this kinda blows. - int r = rowIndex; - Row row; - while (true) { - row = rows.get(r); - if (row.isToken() || row.indexEntry != null) { - break; - } - --r; - } - final IndexEntry indexEntry = row.isToken() ? sortedIndex.get(row.getIndex()) : row.indexEntry; - for (; r <= rowIndex; ++r) { - rows.get(r).indexEntry = indexEntry; - } - assert rows.get(indexEntry.startRow).isToken(); - return indexEntry; - } - } - - public static final class Row implements RAFSerializable { - final int index; - - IndexEntry indexEntry = null; - - public Row(final int index) { - this.index = index; - } - - static final RAFFactory RAF_FACTORY = new RAFFactory() { - public Row create(RandomAccessFile raf) throws IOException { - return new Row(raf.readInt()); - } - }; - - public void write(RandomAccessFile raf) throws IOException { - raf.writeInt(index); - } - - boolean isToken() { - return index < 0; - } - - public int getIndex() { - if (index >= 0) { - return index; - } - return -index - 1; - } - } - - public static final class IndexEntry implements RAFSerializable { - final String word; - final int startRow; - - public IndexEntry(final String word, final int startRow) { - this.word = word; - this.startRow = startRow; - } - - static final RAFFactory RAF_FACTORY = new RAFFactory() { - public IndexEntry create(RandomAccessFile raf) throws IOException { - final String word = raf.readUTF(); - final int startRow = raf.readInt(); - return new IndexEntry(word, startRow); - } - }; - - public void write(final RandomAccessFile raf) throws IOException { - raf.writeUTF(word); - raf.writeInt(startRow); - } - - @Override - public String toString() { - return word + "@" + startRow; - } - - } - -} diff --git a/src/com/hughes/android/dictionary/DictionaryActivity.java b/src/com/hughes/android/dictionary/DictionaryActivity.java index 5c272c5..f1699f1 100644 --- a/src/com/hughes/android/dictionary/DictionaryActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryActivity.java @@ -47,9 +47,7 @@ import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; -import com.hughes.android.dictionary.Dictionary.IndexEntry; -import com.hughes.android.dictionary.Dictionary.LanguageData; -import com.hughes.android.dictionary.Dictionary.Row; +import com.hughes.android.dictionary.engine.Dictionary; import com.hughes.android.dictionary.engine.Language; import com.ibm.icu.text.Collator; @@ -79,13 +77,13 @@ public class DictionaryActivity extends ListActivity { private boolean prefsMightHaveChanged = true; // Never null. - private File wordList; + private File wordList = null; private RandomAccessFile dictRaf = null; private Dictionary dictionary = null; private boolean saveOnlyFirstSubentry = false; // Visible for testing. - LanguageListAdapter languageList = null; + IndexAdapter indexAdapter = null; private SearchOperation searchOperation = null; public DictionaryActivity() { @@ -124,7 +122,6 @@ public class DictionaryActivity extends ListActivity { searchText = (EditText) findViewById(R.id.SearchText); langButton = (Button) findViewById(R.id.LangButton); - Log.d(LOG, "adding text changed listener"); searchText.addTextChangedListener(new SearchTextWatcher()); getListView().setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @@ -209,16 +206,16 @@ public class DictionaryActivity extends ListActivity { Log.d(LOG, "Read dictionary millis: " + (System.currentTimeMillis() - startMillis)); } catch (IOException e) { Log.e(LOG, "Couldn't open dictionary.", e); - this.startActivity(new Intent(this, NoDictionaryActivity.class)); + + this.startActivity(new asdfIntent(this, DictionaryEditActivity.class)); finish(); - throw new Exception(e); } final byte lang = prefs.getInt(PREF_DICT_ACTIVE_LANG, SimpleEntry.LANG1) == SimpleEntry.LANG1 ? SimpleEntry.LANG1 : SimpleEntry.LANG2; - languageList = new LanguageListAdapter(dictionary.languageDatas[lang]); - setListAdapter(languageList); + indexAdapter = new IndexAdapter(dictionary.languageDatas[lang]); + setListAdapter(indexAdapter); prefsMightHaveChanged = false; } @@ -248,7 +245,7 @@ public class DictionaryActivity extends ListActivity { Log.d(LOG, "onPause:" + this); final Editor prefs = PreferenceManager.getDefaultSharedPreferences(this) .edit(); - prefs.putInt(PREF_DICT_ACTIVE_LANG, languageList.languageData.lang); + prefs.putInt(PREF_DICT_ACTIVE_LANG, indexAdapter.languageData.lang); prefs.putString(PREF_ACTIVE_SEARCH_TEXT, searchText.getText().toString()); prefs.commit(); } @@ -269,7 +266,7 @@ public class DictionaryActivity extends ListActivity { return; } waitForSearchEnd(); - languageList = null; + indexAdapter = null; setListAdapter(null); Log.d(LOG, "setListAdapter finished."); dictionary = null; @@ -284,8 +281,8 @@ public class DictionaryActivity extends ListActivity { } public String getSelectedRowRawText(final boolean onlyFirstSubentry) { - final Row row = languageList.languageData.rows.get(getSelectedRow()); - return languageList.languageData.rowToString(row, onlyFirstSubentry); + final Row row = indexAdapter.languageData.rows.get(getSelectedRow()); + return indexAdapter.languageData.rowToString(row, onlyFirstSubentry); } // ---------------------------------------------------------------- @@ -353,12 +350,12 @@ public class DictionaryActivity extends ListActivity { public boolean onPrepareOptionsMenu(final Menu menu) { switchLanguageMenuItem.setTitle(getString(R.string.switchToLanguage, dictionary.languageDatas[SimpleEntry - .otherLang(languageList.languageData.lang)].language.symbol)); + .otherLang(indexAdapter.languageData.lang)].language.symbol)); return super.onPrepareOptionsMenu(menu); } void updateLangButton() { - langButton.setText(languageList.languageData.language.symbol); + langButton.setText(indexAdapter.languageData.language.symbol); } // ---------------------------------------------------------------- @@ -367,25 +364,25 @@ public class DictionaryActivity extends ListActivity { void onLanguageButton() { waitForSearchEnd(); - languageList = new LanguageListAdapter( - dictionary.languageDatas[(languageList.languageData == dictionary.languageDatas[0]) ? 1 + indexAdapter = new IndexAdapter( + dictionary.languageDatas[(indexAdapter.languageData == dictionary.languageDatas[0]) ? 1 : 0]); - Log.d(LOG, "onLanguageButton, newLang=" + languageList.languageData.language.symbol); - setListAdapter(languageList); + Log.d(LOG, "onLanguageButton, newLang=" + indexAdapter.languageData.language.symbol); + setListAdapter(indexAdapter); updateLangButton(); onSearchTextChange(searchText.getText().toString()); } void onUpButton() { - final int destRowIndex = languageList.languageData.getPrevTokenRow(getSelectedRow()); + final int destRowIndex = indexAdapter.languageData.getPrevTokenRow(getSelectedRow()); Log.d(LOG, "onUpButton, destRowIndex=" + destRowIndex); - jumpToRow(languageList, destRowIndex); + jumpToRow(indexAdapter, destRowIndex); } void onDownButton() { - final int destRowIndex = languageList.languageData.getNextTokenRow(getSelectedRow()); + final int destRowIndex = indexAdapter.languageData.getNextTokenRow(getSelectedRow()); Log.d(LOG, "onDownButton, destRowIndex=" + destRowIndex); - jumpToRow(languageList, destRowIndex); + jumpToRow(indexAdapter, destRowIndex); } void onAppendToWordList() { @@ -394,7 +391,7 @@ public class DictionaryActivity extends ListActivity { return; } final StringBuilder rawText = new StringBuilder(); - final String word = languageList.languageData.getIndexEntryForRow(row).word; + final String word = indexAdapter.languageData.getIndexEntryForRow(row).word; rawText.append( new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date())) .append("\t"); @@ -449,7 +446,7 @@ public class DictionaryActivity extends ListActivity { void onSearchTextChange(final String searchText) { Log.d(LOG, "onSearchTextChange: " + searchText); synchronized (this) { - searchOperation = new SearchOperation(languageList, searchText.trim(), searchOperation); + searchOperation = new SearchOperation(indexAdapter, searchText.trim(), searchOperation); searchExecutor.execute(searchOperation); } } @@ -493,10 +490,10 @@ public class DictionaryActivity extends ListActivity { } - private void jumpToRow(final LanguageListAdapter dictionaryListAdapter, + private void jumpToRow(final IndexAdapter dictionaryListAdapter, final int rowIndex) { Log.d(LOG, "jumpToRow: " + rowIndex); - if (dictionaryListAdapter != this.languageList) { + if (dictionaryListAdapter != this.indexAdapter) { Log.w(LOG, "skipping jumpToRow for old list adapter: " + rowIndex); return; } @@ -520,7 +517,7 @@ public class DictionaryActivity extends ListActivity { final int selectedRowIndex = getSelectedRow(); if (!searchText.hasFocus()) { if (selectedRowIndex >= 0) { - final String word = languageList.languageData + final String word = indexAdapter.languageData .getIndexEntryForRow(selectedRowIndex).word; if (!word.equals(searchText.getText().toString())) { Log.d(LOG, "updateSearchText: setText: " + word); @@ -547,12 +544,12 @@ public class DictionaryActivity extends ListActivity { context.startActivity(intent); } - class LanguageListAdapter extends BaseAdapter { + class IndexAdapter extends BaseAdapter { // Visible for testing. final LanguageData languageData; - LanguageListAdapter(final LanguageData languageData) { + IndexAdapter(final LanguageData languageData) { this.languageData = languageData; } @@ -648,13 +645,13 @@ public class DictionaryActivity extends ListActivity { private final class SearchOperation implements Runnable { SearchOperation previousSearchOperation; - final LanguageListAdapter listAdapter; + final IndexAdapter listAdapter; final LanguageData languageData; final String searchText; final AtomicBoolean interrupted = new AtomicBoolean(false); boolean searchFinished = false; - SearchOperation(final LanguageListAdapter listAdapter, + SearchOperation(final IndexAdapter listAdapter, final String searchText, final SearchOperation previousSearchOperation) { this.listAdapter = listAdapter; this.languageData = listAdapter.languageData; diff --git a/src/com/hughes/android/dictionary/DictionaryActivityTest.java b/src/com/hughes/android/dictionary/DictionaryActivityTest.java deleted file mode 100755 index dc0325b..0000000 --- a/src/com/hughes/android/dictionary/DictionaryActivityTest.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.hughes.android.dictionary; - -import com.hughes.android.dictionary.engine.Language; - -import android.test.ActivityInstrumentationTestCase2; - -public class DictionaryActivityTest extends ActivityInstrumentationTestCase2 { - - public DictionaryActivityTest() { - super(DictionaryActivity.class.getPackage().getName(), DictionaryActivity.class); - } - - public void testRunAndFinish() { - final DictionaryActivity dict = getActivity(); - dict.finish(); - } - - abstract class NotifyRunnable implements Runnable { - boolean finished = false; - public final void run() { - assertEquals(false, finished); - run2(); - synchronized (this) { - finished = true; - this.notifyAll(); - } - } - public void waitForFinish() throws InterruptedException { - synchronized (this) { - while (!finished) { - this.wait(); - } - finished = false; - } - getActivity().waitForSearchEnd(); - } - protected abstract void run2(); - } - - private void postAndWait(final NotifyRunnable notifyRunnable) throws Exception { - getActivity().uiHandler.post(notifyRunnable); - notifyRunnable.waitForFinish(); - } - - public void resetDictionary() throws Exception { - final DictionaryActivity dict = getActivity(); - - if (dict.languageList.languageData.language == Language.en) { - postAndWait(switchLangRunnable()); - } - assertEquals(Language.de, dict.languageList.languageData.language); - - postAndWait(new NotifyRunnable() { - protected void run2() { - dict.searchText.setText(""); - dict.onSearchTextChange(""); - } - }); - } - - public void testSwitchLanguage() throws Exception { - final DictionaryActivity dict = getActivity(); - resetDictionary(); - - final NotifyRunnable switchLang = switchLangRunnable(); - - postAndWait(switchLang); - assertEquals(Language.en, dict.languageList.languageData.language); - assertEquals("EN", dict.langButton.getText().toString()); - - postAndWait(switchLang); - assertEquals(Language.de, dict.languageList.languageData.language); - assertEquals("DE", dict.langButton.getText().toString()); - - dict.finish(); - } - - public void testUpDownArrows() throws Exception { - final DictionaryActivity dict = getActivity(); - resetDictionary(); - assertEquals(0, dict.getSelectedItemPosition()); - - final NotifyRunnable upButton = new NotifyRunnable() { - protected void run2() { - dict.onUpButton(); - } - }; - final NotifyRunnable downButton = new NotifyRunnable() { - protected void run2() { - dict.onDownButton(); - } - }; - - dict.getListView().requestFocus(); - assertTrue(dict.getListView().isFocused()); - - String word1 = "-1"; - String word2 = "-14"; - String word3 = "-15"; - - postAndWait(upButton); - assertEquals(0, dict.getSelectedItemPosition()); - assertEquals(word1, dict.searchText.getText().toString()); - - postAndWait(downButton); - assertEquals(2, dict.getSelectedItemPosition()); - assertEquals(word2, dict.searchText.getText().toString()); - - postAndWait(downButton); - assertEquals(4, dict.getSelectedItemPosition()); - assertEquals(word3, dict.searchText.getText().toString()); - - postAndWait(upButton); - assertEquals(2, dict.getSelectedItemPosition()); - assertEquals(word2, dict.searchText.getText().toString()); - - postAndWait(upButton); - assertEquals(0, dict.getSelectedItemPosition()); - assertEquals(word1, dict.searchText.getText().toString()); - - postAndWait(upButton); - assertEquals(0, dict.getSelectedItemPosition()); - - postAndWait(downButton); - assertEquals(2, dict.getSelectedItemPosition()); - - dict.finish(); - } - - private NotifyRunnable switchLangRunnable() { - final NotifyRunnable switchLang = new NotifyRunnable() { - public void run2() { - getActivity().onLanguageButton(); - }}; - return switchLang; - } - -} diff --git a/src/com/hughes/android/dictionary/DownloadActivity.java b/src/com/hughes/android/dictionary/DownloadActivity.java index fca603a..9ad663a 100755 --- a/src/com/hughes/android/dictionary/DownloadActivity.java +++ b/src/com/hughes/android/dictionary/DownloadActivity.java @@ -63,6 +63,7 @@ public class DownloadActivity extends Activity { try { destTmpFile = File.createTempFile("dictionaryDownload", "tmp", destFile .getParentFile()); + destTmpFile.deleteOnExit(); final URL uri = new URL(source); final URLConnection connection = uri.openConnection(); contentLength = connection.getContentLength(); diff --git a/src/com/hughes/android/dictionary/Entry.java b/src/com/hughes/android/dictionary/Entry.java deleted file mode 100644 index b5ba715..0000000 --- a/src/com/hughes/android/dictionary/Entry.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.hughes.android.dictionary; - -import java.io.IOException; -import java.io.RandomAccessFile; - -import com.hughes.util.raf.RAFFactory; -import com.hughes.util.raf.RAFSerializable; - -public interface Entry extends RAFSerializable { - - public static final RAFFactory RAF_FACTORY = new RAFFactory() { - public Entry create(RandomAccessFile raf) throws IOException { - final byte type = raf.readByte(); - switch (type) { - case 0: - return SimpleEntry.RAF_FACTORY.create(raf); - } - throw new RuntimeException("Invalid entry type: " + type); - }}; - - -} diff --git a/src/com/hughes/android/dictionary/NoDictionaryActivity.java b/src/com/hughes/android/dictionary/NoDictionaryActivity.java deleted file mode 100755 index 2e3cfbe..0000000 --- a/src/com/hughes/android/dictionary/NoDictionaryActivity.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.hughes.android.dictionary; - -import java.io.File; - -import android.app.Activity; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.TextView; - -public class NoDictionaryActivity extends Activity { - - /** Called when the activity is first created. */ - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.no_dictionary); - - final Button downloadButton = (Button) findViewById(R.id.downloadDict); - downloadButton.setOnClickListener(new OnClickListener() { - public void onClick(View arg0) { - DictionaryActivity.startDownloadDictActivity(NoDictionaryActivity.this); - }}); - - final Button prefsButton = (Button) findViewById(R.id.preferences); - prefsButton.setOnClickListener(new OnClickListener() { - public void onClick(View arg0) { - startActivity(new Intent(NoDictionaryActivity.this, PreferenceActivity.class)); - }}); - - final Button launchButton = (Button) findViewById(R.id.launchDict); - launchButton.setOnClickListener(new OnClickListener() { - public void onClick(View arg0) { - startActivity(new Intent(NoDictionaryActivity.this, DictionaryActivity.class)); - }}); - } - - @Override - protected void onResume() { - super.onResume(); - - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - final String dictFile = prefs.getString(getString(R.string.dictFileKey), getString(R.string.dictFileDefault)); - final boolean canReadDict = new File(dictFile).canRead(); - - final TextView statusText = (TextView) findViewById(R.id.statusTextId); - if (!canReadDict) { - statusText.setText(getString(R.string.unableToReadDictionaryFile, dictFile)); - } else { - statusText.setText(getString(R.string.dictionaryFileExists, dictFile)); - } - - final Button launchButton = (Button) findViewById(R.id.launchDict); - launchButton.setEnabled(canReadDict); - - } - -} diff --git a/src/com/hughes/android/dictionary/SimpleEntry.java b/src/com/hughes/android/dictionary/SimpleEntry.java deleted file mode 100755 index 4ee8dd4..0000000 --- a/src/com/hughes/android/dictionary/SimpleEntry.java +++ /dev/null @@ -1,214 +0,0 @@ -package com.hughes.android.dictionary; - -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.hughes.util.raf.RAFFactory; - -public final class SimpleEntry implements Entry { - - static final byte LANG1 = 0; - static final byte LANG2 = 1; - - static final Pattern lineSplitPattern = Pattern.compile("\\s::\\s"); - static final Pattern sublineSplitPattern = Pattern.compile("\\s\\|\\s"); - - final String[] lang1; - final String[] lang2; - - SimpleEntry(final String[] lang1, final String[] lang2) { - this.lang1 = lang1; - this.lang2 = lang2; - } - - public static final RAFFactory RAF_FACTORY = new RAFFactory() { - public SimpleEntry create(RandomAccessFile raf) throws IOException { - final int rows = raf.readByte(); - final String[] lang1 = new String[rows]; - final String[] lang2 = new String[rows]; - for (int i = 0; i < lang1.length; ++i) { - lang1[i] = raf.readUTF(); - lang2[i] = raf.readUTF(); - } - return new SimpleEntry(lang1, lang2); - }}; - public void write(RandomAccessFile raf) throws IOException { - assert lang1.length == (byte) lang1.length; - raf.writeByte(lang1.length); - for (int i = 0; i < lang1.length; ++i) { - raf.writeUTF(lang1[i]); - raf.writeUTF(lang2[i]); - } - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof SimpleEntry)) { - return false; - } - final SimpleEntry that = (SimpleEntry) o; - return Arrays.deepEquals(this.lang1, that.lang1) && Arrays.deepEquals(this.lang2, that.lang2); - } - - @Override - public int hashCode() { - return Arrays.deepHashCode(lang1) + Arrays.deepHashCode(lang2); - } - - @Override - public String toString() { - return getRawText(false); - } - - public int getRowCount() { - assert lang1.length == lang2.length; - return lang1.length; - } - - String[] getAllText(final byte lang) { - if (lang == LANG1) { - return lang1; - } - assert lang == LANG2; - return lang2; - } - - String getRawText(boolean onlyFirstSubentry) { - final StringBuilder result = new StringBuilder(); - for (int i = 0; i < (onlyFirstSubentry ? 1 : lang1.length); ++i) { - result.append(i == 0 ? "" : " | ").append(lang1[i]); - } - result.append("\t"); - for (int i = 0; i < (onlyFirstSubentry ? 1 : lang2.length); ++i) { - result.append(i == 0 ? "" : " | ").append(lang2[i]); - } - return result.toString(); - } - - static byte otherLang(final byte lang) { - assert lang == LANG1 || lang == LANG2; - return lang == LANG1 ? LANG2 : LANG1; - } - -/* -Lu Letter, Uppercase -Ll Letter, Lowercase -Lt Letter, Titlecase -Lm Letter, Modifier -Lo Letter, Other -Mn Mark, Nonspacing -Mc Mark, Spacing Combining -Me Mark, Enclosing -Nd Number, Decimal Digit -Nl Number, Letter -No Number, Other -Pc Punctuation, Connector -Pd Punctuation, Dash -Ps Punctuation, Open -Pe Punctuation, Close -Pi Punctuation, Initial quote (may behave like Ps or Pe depending on usage) -Pf Punctuation, Final quote (may behave like Ps or Pe depending on usage) -Po Punctuation, Other -Sm Symbol, Math -Sc Symbol, Currency -Sk Symbol, Modifier -So Symbol, Other -Zs Separator, Space -Zl Separator, Line -Zp Separator, Paragraph -*/ - - static Pattern htmlDecimalCode = Pattern.compile("&#([0-9]+);"); - static Pattern htmlCode = Pattern.compile("&#[^;]+;"); - - static SimpleEntry parseFromLine(String line, final boolean hasMultipleSubentries) { - - line = line.replaceAll("<", "<"); - line = line.replaceAll(">", ">"); - Matcher matcher; - while ((matcher = htmlDecimalCode.matcher(line)).find()) { - final int intVal = Integer.parseInt(matcher.group(1)); - final String charCode = "" + ((char) intVal); - System.out.println("Replacing " + matcher.group() + " with " + charCode); - line = matcher.replaceAll(charCode); - } - if ((matcher = htmlCode.matcher(line)).find()) { - System.err.println("HTML code: " + matcher.group()); - } - - final String[] parts = lineSplitPattern.split(line); - if (parts.length != 2) { - System.err.println("Entry:" + "Invalid line: " + line); - return null; - } - if (!hasMultipleSubentries) { - return new SimpleEntry(new String[] {parts[0].trim()}, new String[] {parts[1].trim()}); - } - - final String[] lang1 = sublineSplitPattern.split(" " + parts[0].trim() + " "); - final String[] lang2 = sublineSplitPattern.split(" " + parts[1].trim() + " "); - if (lang1.length != lang2.length) { - System.err.println("Entry:" + "Invalid subline: " + line); - return null; - } - for (int i = 0; i < lang1.length; ++i) { - lang1[i] = lang1[i].trim(); - lang2[i] = lang2[i].trim(); - } - return new SimpleEntry(lang1, lang2); - } - - static final Map bracketToClose = new LinkedHashMap(); - static { - bracketToClose.put("\"", "\""); - bracketToClose.put(" '", "' "); - } - - // This used to be called WHITESPACE. - static final Pattern NON_TOKEN_CHAR = Pattern.compile("\\s+"); - - public Set getIndexableTokens(final byte lang) { - final Set result = new LinkedHashSet(); - String text = " "; - for (final String subentry : getAllText(lang)) { - text += subentry + " "; - } - - text = text.replaceAll("fig\\.", " "); - text = text.replaceAll("\\{[^\\}]+}", " "); - text = text.replaceAll("\"-", "-"); - text = text.replaceAll("-\"", "-"); - text = text.replaceAll("[\"/\\()<>\\[\\],;?!.]", " "); - text = text.replaceAll("[-:] ", " "); - text = text.replaceAll(" [-:]", " "); - - // Now be really conservative about what we allow inside a token: - // See: http://unicode.org/Public/UNIDATA/UCD.html#General_Category_Values - text = text.replaceAll("[^-:\\p{L}\\p{N}\\p{S}]", " "); - result.addAll(Arrays.asList(NON_TOKEN_CHAR.split(text))); - - text = text.replaceAll("[-]", " "); - result.addAll(Arrays.asList(NON_TOKEN_CHAR.split(text))); - - final Set result2 = new LinkedHashSet(); - for (final String token : result) { - if (isIndexable(token)) { - result2.add(token); - } - } - return result2; - } - - static boolean isIndexable(final String text) { - // Does it have an alpha-numeric anywhere? - return text.matches(".*\\w.*"); - } - -} \ No newline at end of file diff --git a/src/com/hughes/android/dictionary/engine/Dictionary.java b/src/com/hughes/android/dictionary/engine/Dictionary.java index 26dae91..aab0ea2 100644 --- a/src/com/hughes/android/dictionary/engine/Dictionary.java +++ b/src/com/hughes/android/dictionary/engine/Dictionary.java @@ -16,7 +16,10 @@ public class Dictionary implements RAFSerializable { static final int CACHE_SIZE = 5000; + static final String END_OF_DICTIONARY = "END OF DICTIONARY"; + // persisted + final int dictFileVersion; final String dictInfo; final List pairEntries; final List textEntries; @@ -24,6 +27,7 @@ public class Dictionary implements RAFSerializable { final List indices; public Dictionary(final String dictInfo) { + this.dictFileVersion = 0; this.dictInfo = dictInfo; pairEntries = new ArrayList(); textEntries = new ArrayList(); @@ -32,28 +36,30 @@ public class Dictionary implements RAFSerializable { } public Dictionary(final RandomAccessFile raf) throws IOException { + dictFileVersion = raf.readInt(); + if (dictFileVersion != 0) { + throw new IOException("Invalid dictionary version: " + dictFileVersion); + } dictInfo = raf.readUTF(); sources = CachingList.createFullyCached(RAFList.create(raf, EntrySource.SERIALIZER, raf.getFilePointer())); pairEntries = CachingList.create(RAFList.create(raf, PairEntry.SERIALIZER, raf.getFilePointer()), CACHE_SIZE); textEntries = CachingList.create(RAFList.create(raf, TextEntry.SERIALIZER, raf.getFilePointer()), CACHE_SIZE); indices = CachingList.createFullyCached(RAFList.create(raf, indexSerializer, raf.getFilePointer())); - } - - public void print(final PrintStream out) { - out.println("dictInfo=" + dictInfo); - for (final Index index : indices) { - index.print(out); - out.println(); + final String end = raf.readUTF(); + if (!end.equals(END_OF_DICTIONARY)) { + throw new IOException("Dictionary seems corrupt: " + end); } } - + @Override public void write(RandomAccessFile raf) throws IOException { + raf.writeInt(dictFileVersion); raf.writeUTF(dictInfo); RAFList.write(raf, sources, EntrySource.SERIALIZER); RAFList.write(raf, pairEntries, PairEntry.SERIALIZER); RAFList.write(raf, textEntries, TextEntry.SERIALIZER); RAFList.write(raf, indices, indexSerializer); + raf.writeUTF(END_OF_DICTIONARY); } private final RAFListSerializer indexSerializer = new RAFListSerializer() { @@ -65,5 +71,14 @@ public class Dictionary implements RAFSerializable { public void write(RandomAccessFile raf, Index t) throws IOException { t.write(raf); }}; + + public void print(final PrintStream out) { + out.println("dictInfo=" + dictInfo); + for (final Index index : indices) { + index.print(out); + out.println(); + } + } + } \ No newline at end of file -- 2.43.0