net.zionsoft.obadiah.model.translations.TranslationHelper.java Source code

Java tutorial

Introduction

Here is the source code for net.zionsoft.obadiah.model.translations.TranslationHelper.java

Source

/*
 * Obadiah - Simple and Easy-to-Use Bible Reader
 * Copyright (C) 2015 ZionSoft
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.zionsoft.obadiah.model.translations;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import net.zionsoft.obadiah.model.Bible;
import net.zionsoft.obadiah.model.TranslationInfo;
import net.zionsoft.obadiah.model.Verse;
import net.zionsoft.obadiah.model.database.DatabaseHelper;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

public class TranslationHelper {
    public static List<TranslationInfo> toTranslationList(JSONArray jsonArray) throws Exception {
        final int length = jsonArray.length();
        final List<TranslationInfo> translations = new ArrayList<TranslationInfo>(length);
        for (int i = 0; i < length; ++i) {
            final JSONObject translationObject = jsonArray.getJSONObject(i);
            final String name = translationObject.getString("name");
            final String shortName = translationObject.getString("shortName");
            final String language = translationObject.getString("language");
            final String blobKey = translationObject.optString("blobKey", null);
            final int size = translationObject.getInt("size");
            if (TextUtils.isEmpty(name) || TextUtils.isEmpty(shortName) || TextUtils.isEmpty(language)
                    || size <= 0) {
                throw new Exception("Illegal translation info.");
            }
            translations.add(new TranslationInfo(name, shortName, language, blobKey, size));
        }
        return translations;
    }

    public static List<TranslationInfo> sortByLocale(List<TranslationInfo> translations) {
        Collections.sort(translations, new Comparator<TranslationInfo>() {
            @Override
            public int compare(TranslationInfo translation1, TranslationInfo translation2) {
                // first compares with user's default locale
                final Locale userLocale = Locale.getDefault();
                final String userLanguage = userLocale.getLanguage().toLowerCase();
                final String userCountry = userLocale.getCountry().toLowerCase();
                final String[] fields1 = translation1.language.split("_");
                final String[] fields2 = translation2.language.split("_");
                final int score1 = compareLocale(fields1[0], fields1[1], userLanguage, userCountry);
                final int score2 = compareLocale(fields2[0], fields2[1], userLanguage, userCountry);
                int r = score2 - score1;
                if (r != 0)
                    return r;

                // then sorts by language & name
                r = translation1.language.compareTo(translation2.language);
                return r == 0 ? translation1.name.compareTo(translation2.name) : r;
            }
        });
        return translations;
    }

    private static int compareLocale(String language, String country, String targetLanguage, String targetCountry) {
        if (language.equals(targetLanguage))
            return (country.equals(targetCountry)) ? 2 : 1;
        return 0;
    }

    public static List<String> getDownloadedTranslationShortNames(SQLiteDatabase db) {
        Cursor cursor = null;
        try {
            cursor = db.query(true, DatabaseHelper.TABLE_BOOK_NAMES,
                    new String[] { DatabaseHelper.COLUMN_TRANSLATION_SHORT_NAME }, null, null, null, null, null,
                    null);
            final int translationShortName = cursor.getColumnIndex(DatabaseHelper.COLUMN_TRANSLATION_SHORT_NAME);
            final List<String> translations = new ArrayList<String>(cursor.getCount());
            while (cursor.moveToNext())
                translations.add(cursor.getString(translationShortName));
            return translations;
        } finally {
            if (cursor != null)
                cursor.close();
        }
    }

    public static List<String> getBookNames(SQLiteDatabase db, String translationShortName) {
        Cursor cursor = null;
        try {
            cursor = db.query(DatabaseHelper.TABLE_BOOK_NAMES, new String[] { DatabaseHelper.COLUMN_BOOK_NAME },
                    String.format("%s = ?", DatabaseHelper.COLUMN_TRANSLATION_SHORT_NAME),
                    new String[] { translationShortName }, null, null,
                    String.format("%s ASC", DatabaseHelper.COLUMN_BOOK_INDEX));
            final int bookName = cursor.getColumnIndex(DatabaseHelper.COLUMN_BOOK_NAME);
            final List<String> bookNames = new ArrayList<String>(Bible.getBookCount());
            while (cursor.moveToNext())
                bookNames.add(cursor.getString(bookName));
            return bookNames;
        } finally {
            if (cursor != null)
                cursor.close();
        }
    }

    @Nullable
    public static Verse getVerse(SQLiteDatabase db, String translationShortName, String bookName, int book,
            int chapter, int verse) {
        Cursor cursor = null;
        try {
            cursor = db.query(translationShortName, new String[] { DatabaseHelper.COLUMN_TEXT },
                    String.format("%s = ? AND %s = ? AND %s = ?", DatabaseHelper.COLUMN_BOOK_INDEX,
                            DatabaseHelper.COLUMN_CHAPTER_INDEX, DatabaseHelper.COLUMN_VERSE_INDEX),
                    new String[] { Integer.toString(book), Integer.toString(chapter), Integer.toString(verse) },
                    null, null, null);
            if (cursor.moveToFirst()) {
                return new Verse(book, chapter, verse, bookName, cursor.getString(0));
            } else {
                return null;
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
    }

    public static List<Verse> getVerses(SQLiteDatabase db, String translationShortName, String bookName, int book,
            int chapter) {
        Cursor cursor = null;
        try {
            cursor = db.query(translationShortName, new String[] { DatabaseHelper.COLUMN_TEXT },
                    String.format("%s = ? AND %s = ?", DatabaseHelper.COLUMN_BOOK_INDEX,
                            DatabaseHelper.COLUMN_CHAPTER_INDEX),
                    new String[] { Integer.toString(book), Integer.toString(chapter) }, null, null,
                    String.format("%s ASC", DatabaseHelper.COLUMN_VERSE_INDEX));
            final int verse = cursor.getColumnIndex(DatabaseHelper.COLUMN_TEXT);
            final List<Verse> verses = new ArrayList<Verse>(cursor.getCount());
            int verseIndex = 0;
            while (cursor.moveToNext())
                verses.add(new Verse(book, chapter, verseIndex++, bookName, cursor.getString(verse)));
            return verses;
        } finally {
            if (cursor != null)
                cursor.close();
        }
    }

    public static List<Verse> searchVerses(SQLiteDatabase db, String translationShortName, List<String> bookNames,
            String keyword) {
        Cursor cursor = null;
        try {
            cursor = db.query(translationShortName,
                    new String[] { DatabaseHelper.COLUMN_BOOK_INDEX, DatabaseHelper.COLUMN_CHAPTER_INDEX,
                            DatabaseHelper.COLUMN_VERSE_INDEX, DatabaseHelper.COLUMN_TEXT },
                    String.format("%s LIKE ?", DatabaseHelper.COLUMN_TEXT),
                    new String[] { String.format("%%%s%%", keyword.trim().replaceAll("\\s+", "%")) }, null, null,
                    String.format(" %s ASC, %s ASC, %s ASC", DatabaseHelper.COLUMN_BOOK_INDEX,
                            DatabaseHelper.COLUMN_CHAPTER_INDEX, DatabaseHelper.COLUMN_VERSE_INDEX));
            final int count = cursor.getCount();
            if (count == 0)
                return Collections.emptyList();

            final int bookIndex = cursor.getColumnIndex(DatabaseHelper.COLUMN_BOOK_INDEX);
            final int chapterIndex = cursor.getColumnIndex(DatabaseHelper.COLUMN_CHAPTER_INDEX);
            final int verseIndex = cursor.getColumnIndex(DatabaseHelper.COLUMN_VERSE_INDEX);
            final int verseText = cursor.getColumnIndex(DatabaseHelper.COLUMN_TEXT);
            final List<Verse> verses = new ArrayList<Verse>(count);
            while (cursor.moveToNext()) {
                final int book = cursor.getInt(bookIndex);
                verses.add(new Verse(book, cursor.getInt(chapterIndex), cursor.getInt(verseIndex),
                        bookNames.get(book), cursor.getString(verseText)));
            }
            return verses;
        } finally {
            if (cursor != null)
                cursor.close();
        }
    }

    public static void createTranslationTable(SQLiteDatabase db, String translationShortName) {
        db.execSQL(String.format(
                "CREATE TABLE %s (%s INTEGER NOT NULL, %s INTEGER NOT NULL, %s INTEGER NOT NULL, %s TEXT NOT NULL);",
                translationShortName, DatabaseHelper.COLUMN_BOOK_INDEX, DatabaseHelper.COLUMN_CHAPTER_INDEX,
                DatabaseHelper.COLUMN_VERSE_INDEX, DatabaseHelper.COLUMN_TEXT));
        db.execSQL(String.format("CREATE INDEX INDEX_%s ON %s (%s, %s, %s);", translationShortName,
                translationShortName, DatabaseHelper.COLUMN_BOOK_INDEX, DatabaseHelper.COLUMN_CHAPTER_INDEX,
                DatabaseHelper.COLUMN_VERSE_INDEX));
    }

    public static void saveBookNames(SQLiteDatabase db, JSONObject booksInfoObject) throws Exception {
        final String translationShortName = booksInfoObject.getString("shortName");
        final ContentValues bookNamesValues = new ContentValues(3);
        bookNamesValues.put(DatabaseHelper.COLUMN_TRANSLATION_SHORT_NAME, translationShortName);
        final JSONArray booksArray = booksInfoObject.getJSONArray("books");
        for (int i = 0; i < Bible.getBookCount(); ++i) {
            bookNamesValues.put(DatabaseHelper.COLUMN_BOOK_INDEX, i);

            final String bookName = booksArray.getString(i);
            if (TextUtils.isEmpty(bookName))
                throw new Exception("Illegal books.json file: " + translationShortName);
            bookNamesValues.put(DatabaseHelper.COLUMN_BOOK_NAME, bookName);

            db.insert(DatabaseHelper.TABLE_BOOK_NAMES, null, bookNamesValues);
        }
    }

    public static void saveVerses(SQLiteDatabase db, String translationShortName, int bookIndex, int chapterIndex,
            JSONObject versesObject) throws Exception {
        final ContentValues versesValues = new ContentValues(4);
        versesValues.put(DatabaseHelper.COLUMN_BOOK_INDEX, bookIndex);
        versesValues.put(DatabaseHelper.COLUMN_CHAPTER_INDEX, chapterIndex);
        final JSONArray paragraphArray = versesObject.getJSONArray("verses");
        final int paragraphCount = paragraphArray.length();
        boolean hasNonEmptyVerse = false;
        for (int verseIndex = 0; verseIndex < paragraphCount; ++verseIndex) {
            versesValues.put(DatabaseHelper.COLUMN_VERSE_INDEX, verseIndex);

            final String verse = paragraphArray.getString(verseIndex);
            if (!hasNonEmptyVerse && !TextUtils.isEmpty(verse))
                hasNonEmptyVerse = true;
            versesValues.put(DatabaseHelper.COLUMN_TEXT, verse);

            db.insert(translationShortName, null, versesValues);
        }
        if (!hasNonEmptyVerse) {
            throw new Exception(
                    String.format("Empty chapter: %s %d-%d", translationShortName, bookIndex, chapterIndex));
        }
    }

    public static void removeTranslation(SQLiteDatabase db, String translationShortName) {
        db.execSQL(String.format("DROP TABLE IF EXISTS %s", translationShortName));

        db.delete(DatabaseHelper.TABLE_BOOK_NAMES,
                String.format("%s = ?", DatabaseHelper.COLUMN_TRANSLATION_SHORT_NAME),
                new String[] { translationShortName });
    }
}