org.liberty.android.fantastischmemo.downloader.DownloaderSS.java Source code

Java tutorial

Introduction

Here is the source code for org.liberty.android.fantastischmemo.downloader.DownloaderSS.java

Source

/*
Copyright (C) 2010 Haowen Ning
    
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 2
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    
*/
package org.liberty.android.fantastischmemo.downloader;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

import javax.inject.Inject;

import org.json.JSONArray;
import org.json.JSONObject;
import org.liberty.android.fantastischmemo.AMEnv;
import org.liberty.android.fantastischmemo.AnyMemoDBOpenHelper;
import org.liberty.android.fantastischmemo.AnyMemoDBOpenHelperManager;
import org.liberty.android.fantastischmemo.R;
import org.liberty.android.fantastischmemo.dao.CardDao;
import org.liberty.android.fantastischmemo.domain.Card;
import org.liberty.android.fantastischmemo.domain.Category;
import org.liberty.android.fantastischmemo.domain.LearningData;
import org.liberty.android.fantastischmemo.utils.RecentListUtil;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Handler;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.TextView;

/*
 * This is the downloader class for StudyStack
 */
public class DownloaderSS extends DownloaderBase implements ListView.OnScrollListener {
    private static final String TAG = "org.liberty.android.fantastischmemo.downloader.DownloaderSS";
    private static final String SS_API_GET_DECK = "http://www.studystack.com/servlet/json?studyStackId=";
    private static final String SS_API_GET_CATEGORIES = "http://www.studystack.com/servlet/categoryListJson";
    private static final String SS_API_GET_CATEGORY_CONTENT = "http://www.studystack.com/servlet/categoryStackListJson?sortOrder=stars&categoryId=";
    private DownloadListAdapter dlAdapter;
    private Stack<List<DownloadItem>> dlStack;
    private Stack<String> categoryIdStack;
    private ListView listView;
    private ProgressDialog mProgressDialog;
    private Handler mHandler;
    private List<DownloadItem> categoryList = null;

    private DownloaderUtils downloaderUtils;

    private RecentListUtil recentListUtil;

    @Inject
    public void setDownloaderUtils(DownloaderUtils downloaderUtils) {
        this.downloaderUtils = downloaderUtils;
    }

    @Inject
    public void setRecentListUtil(RecentListUtil recentListUtil) {
        this.recentListUtil = recentListUtil;
    }

    @Override
    protected void initialRetrieve() {
        dlAdapter = new DownloadListAdapter(this, R.layout.filebrowser_item);
        dlStack = new Stack<List<DownloadItem>>();
        categoryIdStack = new Stack<String>();
        mHandler = new Handler();
        listView = (ListView) findViewById(R.id.file_list);
        listView.setOnScrollListener(this);
        listView.setAdapter(dlAdapter);
        mProgressDialog = ProgressDialog.show(DownloaderSS.this, getString(R.string.loading_please_wait),
                getString(R.string.loading_connect_net), true, true, new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        finish();
                    }
                });
        new Thread() {
            public void run() {
                try {
                    categoryList = retrieveCategories();
                    mHandler.post(new Runnable() {
                        public void run() {
                            showRootCategories();
                            mProgressDialog.dismiss();
                        }
                    });
                } catch (final Exception e) {
                    mHandler.post(new Runnable() {
                        public void run() {
                            mProgressDialog.dismiss();
                            new AlertDialog.Builder(DownloaderSS.this)
                                    .setTitle(R.string.downloader_connection_error)
                                    .setMessage(
                                            getString(R.string.downloader_connection_error_message) + e.toString())
                                    .setPositiveButton(getString(R.string.ok_text),
                                            new DialogInterface.OnClickListener() {
                                                @Override
                                                public void onClick(DialogInterface dialog, int which) {
                                                    finish();
                                                }
                                            })
                                    .create().show();
                        }
                    });
                }

            }
        }.start();

    }

    protected void openCategory(final DownloadItem di) {
        mProgressDialog = ProgressDialog.show(this, getString(R.string.loading_please_wait),
                getString(R.string.loading_connect_net), true, true, new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        finish();
                    }
                });
        new Thread() {
            public void run() {
                try {
                    final List<DownloadItem> databaseList = retrieveDatabaseList(di);
                    dlStack.push(dlAdapter.getList());
                    categoryIdStack.push(di.getExtras("id"));
                    mHandler.post(new Runnable() {
                        public void run() {
                            dlAdapter.clear();
                            for (DownloadItem i : categoryList) {
                                if (i.getExtras("pid").equals(di.getExtras("id"))) {
                                    dlAdapter.add(i);
                                }
                            }
                            dlAdapter.addList(databaseList);
                            listView.setSelection(0);
                            mProgressDialog.dismiss();
                        }
                    });

                } catch (final Exception e) {
                    mHandler.post(new Runnable() {
                        public void run() {
                            Log.e(TAG, "Error obtaining databases", e);
                            new AlertDialog.Builder(DownloaderSS.this)
                                    .setTitle(getString(R.string.downloader_connection_error))
                                    .setMessage(
                                            getString(R.string.downloader_connection_error_message) + e.toString())
                                    .setNeutralButton(getString(R.string.back_menu_text),
                                            new DialogInterface.OnClickListener() {
                                                @Override
                                                public void onClick(DialogInterface arg0, int arg1) {
                                                    finish();
                                                }
                                            })
                                    .create().show();
                        }
                    });
                }
            }
        }.start();
    }

    protected DownloadItem getDownloadItem(int position) {
        return dlAdapter.getItem(position);
    }

    protected void goBack() {
        if (dlStack == null || dlStack.empty()) {
            finish();
        } else {
            dlAdapter.clear();
            dlAdapter.addList(dlStack.pop());
            listView.setSelection(0);
            if (!categoryIdStack.empty()) {
                categoryIdStack.pop();
            }
        }
    }

    protected void fetchDatabase(final DownloadItem di) {
        View alertView = View.inflate(this, R.layout.link_alert, null);
        TextView textView = (TextView) alertView.findViewById(R.id.link_alert_message);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setText(
                Html.fromHtml(getString(R.string.downloader_download_alert_message) + di.getDescription()));

        new AlertDialog.Builder(this).setView(alertView)
                .setTitle(getString(R.string.downloader_download_alert) + di.getTitle())
                .setPositiveButton(getString(R.string.yes_text), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        mProgressDialog = ProgressDialog.show(DownloaderSS.this,
                                getString(R.string.loading_please_wait), getString(R.string.loading_downloading));
                        new Thread() {
                            public void run() {
                                try {
                                    downloadDatabase(di);
                                    mHandler.post(new Runnable() {
                                        public void run() {
                                            mProgressDialog.dismiss();
                                            String dbpath = AMEnv.DEFAULT_ROOT_PATH;
                                            new AlertDialog.Builder(DownloaderSS.this)
                                                    .setTitle(R.string.downloader_download_success)
                                                    .setMessage(
                                                            getString(R.string.downloader_download_success_message)
                                                                    + dbpath + di.getTitle() + ".db")
                                                    .setPositiveButton(R.string.ok_text, null).create().show();
                                        }
                                    });

                                } catch (final Exception e) {
                                    Log.e(TAG, "Error downloading", e);
                                    mHandler.post(new Runnable() {
                                        public void run() {
                                            mProgressDialog.dismiss();
                                            new AlertDialog.Builder(DownloaderSS.this)
                                                    .setTitle(R.string.downloader_download_fail)
                                                    .setMessage(getString(R.string.downloader_download_fail_message)
                                                            + " " + e.toString())
                                                    .setPositiveButton(R.string.ok_text, null).create().show();
                                        }
                                    });
                                }
                            }
                        }.start();
                    }
                }).setNegativeButton(getString(R.string.no_text), null).show();
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (totalItemCount <= 0) {
            return;
        }
        if (totalItemCount >= 25 && (firstVisibleItem + visibleItemCount == totalItemCount)) {
            DownloadItem di = dlAdapter.getItem(totalItemCount - 1);
            if (di.getType() == DownloadItem.ItemType.Database) {
                try {
                    int page = Integer.parseInt(di.getExtras("page"));
                    page += 1;
                    DownloadItem nextPage = new DownloadItem();
                    nextPage.setExtras("id", categoryIdStack.peek());
                    nextPage.setExtras("page", Integer.toString(page));
                    List<DownloadItem> nextPageItems = retrieveDatabaseList(nextPage);
                    dlAdapter.addList(nextPageItems);

                } catch (Exception e) {
                    Log.e(TAG, "Error to scroll", e);
                }
            }

        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    private List<DownloadItem> retrieveCategories() throws Exception {
        List<DownloadItem> diList = new LinkedList<DownloadItem>();
        JSONArray jsonArray = new JSONArray(downloaderUtils.downloadJSONString(SS_API_GET_CATEGORIES));
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonItem = jsonArray.getJSONObject(i);
            DownloadItem di = new DownloadItem();
            di.setType(DownloadItem.ItemType.Category);
            di.setTitle(jsonItem.getString("name"));
            di.setExtras("id", jsonItem.getString("id"));
            di.setExtras("pid", jsonItem.getString("parentId"));
            di.setExtras("page", "1");

            if (di.getTitle() != null) {
                diList.add(di);
            }
        }
        return diList;
    }

    private List<DownloadItem> retrieveDatabaseList(DownloadItem category) throws Exception {
        List<DownloadItem> diList = new LinkedList<DownloadItem>();
        String url = SS_API_GET_CATEGORY_CONTENT + category.getExtras("id");
        String page = category.getExtras("page");
        if (page != null) {
            url += "&page=" + page;
        } else {
            page = "1";
        }

        JSONArray jsonArray = new JSONArray(downloaderUtils.downloadJSONString(url));
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonItem = jsonArray.getJSONObject(i);
            DownloadItem di = new DownloadItem();
            di.setType(DownloadItem.ItemType.Database);
            di.setTitle(jsonItem.getString("stackName"));
            di.setDescription(jsonItem.getString("description"));
            di.setExtras("id", jsonItem.getString("id"));
            di.setAddress(SS_API_GET_DECK + jsonItem.getString("id"));
            di.setExtras("page", page);
            if (di.getTitle() != null) {
                diList.add(di);
            }
        }
        return diList;
    }

    private void showRootCategories() {
        if (categoryList == null) {
            return;
        }
        for (DownloadItem di : categoryList) {
            if (di.getExtras("pid").equals("0")) {
                dlAdapter.add(di);
            }
        }
    }

    private void downloadDatabase(DownloadItem di) throws Exception {
        String url = di.getAddress();
        String jsonString = downloaderUtils.downloadJSONString(url);
        JSONObject jsonObject = new JSONObject(jsonString);
        JSONArray jsonDataArray = jsonObject.getJSONArray("data");
        List<Card> cardList = new LinkedList<Card>();
        for (int i = 0; i < jsonDataArray.length(); i++) {
            JSONArray jsonItemArray = jsonDataArray.getJSONArray(i);
            String question = jsonItemArray.getString(0);
            String answer = jsonItemArray.getString(1);
            if (question != null && !question.equals("")) {
                Card card = new Card();
                card.setQuestion(question);
                card.setAnswer(answer);
                card.setOrdinal(i + 1);
                card.setCategory(new Category());
                card.setLearningData(new LearningData());
                cardList.add(card);
            }

        }
        String dbname = di.getTitle() + ".db";
        String dbpath = AMEnv.DEFAULT_ROOT_PATH;
        String fullpath = dbpath + dbname;
        AnyMemoDBOpenHelper helper = AnyMemoDBOpenHelperManager.getHelper(DownloaderSS.this, fullpath);
        try {
            CardDao cardDao = helper.getCardDao();
            cardDao.createCards(cardList);
            long count = helper.getCardDao().getTotalCount(null);
            if (count <= 0L) {
                throw new RuntimeException("Downloaded empty db.");
            }
        } finally {
            AnyMemoDBOpenHelperManager.releaseHelper(helper);
        }
        recentListUtil.addToRecentList(fullpath);
    }

}