diff --git a/src/ui/android/README b/src/ui/android/README index 16d9c1104..7adb7fe50 100644 --- a/src/ui/android/README +++ b/src/ui/android/README @@ -30,6 +30,9 @@ Build JNI code: $ cd jni $ $ANDROID_NDK_LOCATION/ndk-build +Build the semantic database code: + +$ runghc glosses.hs Build APK: diff --git a/src/ui/android/glosses.hs b/src/ui/android/glosses.hs new file mode 100644 index 000000000..0bb3c8af0 --- /dev/null +++ b/src/ui/android/glosses.hs @@ -0,0 +1,19 @@ +import SG + +main = do + ls <- fmap lines $ readFile "../../../lib/src/translator/Dictionary.gf" + writeFile "assets/glosses.txt" (unlines ["<"++fn++",gloss,"++show gloss++">" | Just (fn,gloss) <- map gloss ls]) + +gloss l = + case words l of + ("fun":fn:_) -> case dropWhile (/='\t') l of + '\t':l -> Just (fn,l) + _ -> Nothing + _ -> Nothing + +test = do + db <- openSG "semantics.db" + ls <- fmap lines $ readFile "assets/glosses.txt" + inTransaction db $ + sequence_ [insertTriple db s p o | Just (s,p,o) <- map readTriple ls] + closeSG db diff --git a/src/ui/android/src/org/grammaticalframework/ui/android/DBManager.java b/src/ui/android/src/org/grammaticalframework/ui/android/DBManager.java deleted file mode 100644 index e395ccf75..000000000 --- a/src/ui/android/src/org/grammaticalframework/ui/android/DBManager.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.grammaticalframework.ui.android; - -import android.content.Context; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteException; -import android.database.sqlite.SQLiteOpenHelper; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class DBManager extends SQLiteOpenHelper { - private final Context mContext; - - public DBManager(Context context) { - super(context, "defs.db", null, 1); - mContext = context; - } - - @Override - public synchronized SQLiteDatabase getReadableDatabase() { - copyDatabaseFromAssets(); - return super.getReadableDatabase(); - } - - @Override - public synchronized SQLiteDatabase getWritableDatabase() { - copyDatabaseFromAssets(); - return super.getWritableDatabase(); - } - - private void copyDatabaseFromAssets() throws SQLiteException { - String path = mContext.getDatabasePath(getDatabaseName()).getPath(); - - File file = new File(path); - if (file.exists()) { - return; - } - - InputStream ins = null; - OutputStream outs = null; - - try { - File dir = new File(mContext.getApplicationInfo().dataDir + "/databases"); - if (!dir.exists()) { - dir.mkdir(); - } - - ins = mContext.getAssets().open(getDatabaseName()); - outs = new FileOutputStream(path); - - byte[] buffer = new byte[1024]; - int length; - while ((length = ins.read(buffer)) > 0) { - outs.write(buffer, 0, length); - } - outs.flush(); - } catch (IOException e) { - SQLiteException se = new SQLiteException("Unable to write " + path + " to data directory"); - se.setStackTrace(e.getStackTrace()); - - if (outs != null) { - try { - outs.close(); - } catch (IOException e2) { - } - outs = null; - } - - file.delete(); - throw se; - } finally { - try { - if (outs != null) - outs.close(); - if (ins != null) - ins.close(); - } catch (IOException e) { - } - } - } - - @Override - public final void onCreate(SQLiteDatabase db) { - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - } -} diff --git a/src/ui/android/src/org/grammaticalframework/ui/android/SemanticGraphManager.java b/src/ui/android/src/org/grammaticalframework/ui/android/SemanticGraphManager.java new file mode 100644 index 000000000..19080dfef --- /dev/null +++ b/src/ui/android/src/org/grammaticalframework/ui/android/SemanticGraphManager.java @@ -0,0 +1,97 @@ +package org.grammaticalframework.ui.android; + +import java.io.*; +import android.content.Context; + +import org.grammaticalframework.sg.*; +import org.grammaticalframework.pgf.*; + +public class SemanticGraphManager implements Closeable { + private final Context mContext; + private SG mDB; + + public static final String GLOSSES_FILE_NAME = "glosses.txt"; + public static final String DATABASE_FILE_NAME = "semantics.db"; + + public SemanticGraphManager(Context context) { + mContext = context; + mDB = null; + } + + private void createDatabaseFromAssets() throws SGError, IOException { + if (mDB != null) + return; + + String path = mContext.getDatabasePath(DATABASE_FILE_NAME).getPath(); + + boolean exists = false; + + File file = new File(path); + if (((GFTranslator) mContext.getApplicationContext()).getTranslator().isUpgraded("db_version")) { + file.delete(); + } else { + if (file.exists()) { + exists = true; + } + } + + File dir = new File(mContext.getApplicationInfo().dataDir + "/databases"); + if (!dir.exists()) { + dir.mkdir(); + } + + mDB = SG.openSG(path); + if (exists) + return; + + BufferedReader br = new BufferedReader( + new InputStreamReader( + mContext.getAssets().open(GLOSSES_FILE_NAME))); + + try { + mDB.beginTrans(); + + String line; + while ((line = br.readLine()) != null) { + Expr[] triple = SG.readTriple(line); + mDB.insertTriple(triple[0],triple[1],triple[2]); + } + + mDB.commit(); + } catch (IOException e) { + mDB.rollback(); + throw e; + } catch (SGError e) { + mDB.rollback(); + throw e; + } finally { + br.close(); + } + } + + public void close() { + if (mDB != null) { + mDB.close(); + mDB = null; + } + } + + public Expr getGloss(Expr lemma) { + Expr obj = null; + + try { + createDatabaseFromAssets(); + TripleResult res = mDB.queryTriple(lemma, Expr.readExpr("gloss"), null); + if (res.hasNext()) { + obj = res.getObject(); + } + res.close(); + } catch (IOException e) { + // nothing + } catch (SGError e) { + // nothing + } + + return obj; + } +} diff --git a/src/ui/android/src/org/grammaticalframework/ui/android/Translator.java b/src/ui/android/src/org/grammaticalframework/ui/android/Translator.java index 94cb67b2b..aaae8368f 100644 --- a/src/ui/android/src/org/grammaticalframework/ui/android/Translator.java +++ b/src/ui/android/src/org/grammaticalframework/ui/android/Translator.java @@ -2,6 +2,7 @@ package org.grammaticalframework.ui.android; import android.content.Context; import android.content.SharedPreferences; +import android.content.pm.PackageManager.NameNotFoundException; import android.util.Log; import android.util.Pair; import android.view.inputmethod.CompletionInfo; @@ -48,7 +49,7 @@ public class Translator { private ConcrLoader mSourceLoader; private ConcrLoader mTargetLoader; private ConcrLoader mOtherLoader; - private DBManager mDBManager; + private SemanticGraphManager mSGManager; private static final String SOURCE_LANG_KEY = "source_lang"; private static final String TARGET_LANG_KEY = "target_lang"; @@ -99,7 +100,7 @@ public class Translator { mOtherLoader = null; - mDBManager = new DBManager(context); + mSGManager = new SemanticGraphManager(context); } public List getAvailableLanguages() { @@ -366,27 +367,26 @@ public class Translator { } public String getInflectionTable(String lemma) { - String def = ""; -/* SQLiteDatabase db = mDBManager.getReadableDatabase(); - Cursor crs = db.rawQuery("select def from defs where fun=?1", new String[] { lemma }); - if (crs.moveToNext()) { - def = escapeHtml(crs.getString(0)); - } - crs.close();*/ + Expr lemmaExpr = Expr.readExpr(lemma); + Expr gloss = mSGManager.getGloss(lemmaExpr); + Expr empty = Expr.readExpr("\"\""); Concr targetLang = getTargetConcr(); String cat = getGrammar().getFunctionType(lemma).getCategory(); if (targetLang.hasLinearization(lemma) && targetLang.hasLinearization("Inflection"+cat)) { - Expr e = Expr.readExpr("MkDocument \""+def+"\" (Inflection"+cat+" "+lemma+") \"\""); + if (gloss == null) + gloss = empty; + + Expr e = new Expr("MkDocument", gloss, Expr.readExpr("Inflection"+cat+" "+lemma), empty); String html = "" + targetLang.linearize(e) + ""; return html; - } else if (def != "") { - return "

"+def+"

"; + } else if (gloss != null) { + return "

"+targetLang.linearize(gloss)+"

"; } else { return null; } @@ -555,4 +555,21 @@ public class Translator { } } } + + public boolean isUpgraded(String key) { + int old_code = mSharedPref.getInt(key, 0); + + int new_code = 0; + try { + new_code = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode; + } catch (NameNotFoundException e) { + // Huh? Really? + } + + SharedPreferences.Editor editor = mSharedPref.edit(); + editor.putInt(key, new_code); + editor.commit(); + + return (old_code != new_code); + } }