org.digitalcampus.oppia.task.SubmitTrackerMultipleTask.java Source code

Java tutorial

Introduction

Here is the source code for org.digitalcampus.oppia.task.SubmitTrackerMultipleTask.java

Source

/* 
 * This file is part of OppiaMobile - https://digital-campus.org/
 * 
 * OppiaMobile 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.
 * 
 * OppiaMobile 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 OppiaMobile. If not, see <http://www.gnu.org/licenses/>.
 */

package org.digitalcampus.oppia.task;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.digitalcampus.oppia.activity.PrefsActivity;
import org.digitalcampus.oppia.application.DatabaseManager;
import org.digitalcampus.oppia.application.DbHelper;
import org.digitalcampus.oppia.application.MobileLearning;
import org.digitalcampus.oppia.listener.TrackerServiceListener;
import org.digitalcampus.oppia.model.TrackerLog;
import org.digitalcampus.oppia.model.User;
import org.digitalcampus.oppia.utils.HTTPConnectionUtils;
import org.digitalcampus.oppia.utils.MetaDataUtils;
import org.json.JSONException;
import org.json.JSONObject;

import com.splunk.mint.Mint;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;

public class SubmitTrackerMultipleTask extends AsyncTask<Payload, Integer, Payload> {

    public final static String TAG = SubmitTrackerMultipleTask.class.getSimpleName();

    private Context ctx;
    private SharedPreferences prefs;
    private TrackerServiceListener trackerServiceListener;

    public SubmitTrackerMultipleTask(Context ctx) {
        this.ctx = ctx;
        prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
    }

    @Override
    protected Payload doInBackground(Payload... params) {
        Payload payload = new Payload();

        try {
            DbHelper db = new DbHelper(ctx);
            ArrayList<User> users = db.getAllUsers();
            DatabaseManager.getInstance().closeDatabase();

            for (User u : users) {
                DbHelper db1 = new DbHelper(ctx);
                payload = db1.getUnsentTrackers(u.getUserId());
                DatabaseManager.getInstance().closeDatabase();

                @SuppressWarnings("unchecked")
                Collection<Collection<TrackerLog>> result = (Collection<Collection<TrackerLog>>) split(
                        (Collection<Object>) payload.getData(), MobileLearning.MAX_TRACKER_SUBMIT);

                for (Collection<TrackerLog> trackerBatch : result) {
                    String dataToSend = createDataString(trackerBatch);
                    Log.d(TAG, "Debug data to Send: " + dataToSend);
                    try {

                        HTTPConnectionUtils client = new HTTPConnectionUtils(ctx);
                        String url = client.getFullURL(MobileLearning.TRACKER_PATH);
                        HttpPatch httpPatch = new HttpPatch(url);

                        StringEntity se = new StringEntity(dataToSend, "utf8");
                        se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                        httpPatch.setEntity(se);

                        httpPatch.addHeader(client.getAuthHeader(u.getUsername(), u.getApiKey()));

                        // make request
                        HttpResponse response = client.execute(httpPatch);

                        InputStream content = response.getEntity().getContent();
                        BufferedReader buffer = new BufferedReader(new InputStreamReader(content), 4096);
                        String responseStr = "";
                        String s = "";

                        while ((s = buffer.readLine()) != null) {
                            responseStr += s;
                        }
                        Log.d(TAG, responseStr);
                        switch (response.getStatusLine().getStatusCode()) {
                        case 200: // submitted
                            for (TrackerLog tl : trackerBatch) {
                                DbHelper db2 = new DbHelper(ctx);
                                db2.markLogSubmitted(tl.getId());
                                DatabaseManager.getInstance().closeDatabase();
                            }
                            payload.setResult(true);
                            // update points
                            JSONObject jsonResp = new JSONObject(responseStr);
                            DbHelper dbpb = new DbHelper(ctx);
                            dbpb.updateUserPoints(u.getUserId(), jsonResp.getInt("points"));
                            dbpb.updateUserBadges(u.getUserId(), jsonResp.getInt("badges"));
                            DatabaseManager.getInstance().closeDatabase();

                            Editor editor = prefs.edit();
                            try {
                                editor.putBoolean(PrefsActivity.PREF_SCORING_ENABLED,
                                        jsonResp.getBoolean("scoring"));
                                editor.putBoolean(PrefsActivity.PREF_BADGING_ENABLED,
                                        jsonResp.getBoolean("badging"));
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                            editor.commit();

                            try {
                                JSONObject metadata = jsonResp.getJSONObject("metadata");
                                MetaDataUtils mu = new MetaDataUtils(ctx);
                                mu.saveMetaData(metadata, prefs);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            break;
                        case 400: // submitted but invalid digest - returned 400 Bad Request - so record as submitted so doesn't keep trying
                            for (TrackerLog tl : trackerBatch) {
                                DbHelper db3 = new DbHelper(ctx);
                                db3.markLogSubmitted(tl.getId());
                                DatabaseManager.getInstance().closeDatabase();
                            }
                            ;
                            payload.setResult(true);
                            break;
                        default:
                            payload.setResult(false);
                        }

                    } catch (UnsupportedEncodingException e) {
                        payload.setResult(false);
                    } catch (ClientProtocolException e) {
                        payload.setResult(false);
                    } catch (IOException e) {
                        payload.setResult(false);
                    } catch (JSONException e) {
                        Mint.logException(e);
                        e.printStackTrace();
                        payload.setResult(false);
                    }
                    publishProgress(0);
                }

            }

        } catch (IllegalStateException ise) {
            ise.printStackTrace();
            payload.setResult(false);
        }

        Editor editor = prefs.edit();
        long now = System.currentTimeMillis() / 1000;
        editor.putLong(PrefsActivity.PREF_TRIGGER_POINTS_REFRESH, now);
        editor.commit();

        return payload;
    }

    @Override
    protected void onProgressUpdate(Integer... obj) {
        synchronized (this) {
            if (trackerServiceListener != null) {
                trackerServiceListener.trackerProgressUpdate();
            }
        }
    }

    @Override
    protected void onPostExecute(Payload p) {
        synchronized (this) {
            if (trackerServiceListener != null) {
                trackerServiceListener.trackerComplete();
            }
        }
        // reset submittask back to null after completion - so next call can run properly
        MobileLearning app = (MobileLearning) ctx.getApplicationContext();
        app.omSubmitTrackerMultipleTask = null;

    }

    public void setTrackerServiceListener(TrackerServiceListener tsl) {
        trackerServiceListener = tsl;
    }

    private static Collection<Collection<TrackerLog>> split(Collection<Object> bigCollection, int maxBatchSize) {
        Collection<Collection<TrackerLog>> result = new ArrayList<Collection<TrackerLog>>();

        ArrayList<TrackerLog> currentBatch = null;
        for (Object obj : bigCollection) {
            TrackerLog tl = (TrackerLog) obj;
            if (currentBatch == null) {
                currentBatch = new ArrayList<TrackerLog>();
            } else if (currentBatch.size() >= maxBatchSize) {
                result.add(currentBatch);
                currentBatch = new ArrayList<TrackerLog>();
            }

            currentBatch.add(tl);
        }

        if (currentBatch != null) {
            result.add(currentBatch);
        }

        return result;
    }

    private String createDataString(Collection<TrackerLog> collection) {
        String s = "{\"objects\":[";
        int counter = 0;
        for (TrackerLog tl : collection) {
            counter++;
            s += tl.getContent();
            if (counter != collection.size()) {
                s += ",";
            }
        }
        s += "]}";
        return s;
    }

}