com.aujur.ebookreader.sync.PageTurnerWebProgressService.java Source code

Java tutorial

Introduction

Here is the source code for com.aujur.ebookreader.sync.PageTurnerWebProgressService.java

Source

/*
 * Copyright (C) 2011 Alex Kuiper
 * 
 * This file is part of PageTurner
 *
 * PageTurner 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.
 *
 * PageTurner 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 PageTurner.  If not, see <http://www.gnu.org/licenses/>.*
 */
package com.aujur.ebookreader.sync;

import android.content.Context;

import com.aujur.ebookreader.Configuration;
import com.google.inject.Inject;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import roboguice.inject.ContextSingleton;

import java.io.IOException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@ContextSingleton
public class PageTurnerWebProgressService implements ProgressService {

    private static final Logger LOG = LoggerFactory.getLogger(PageTurnerWebProgressService.class);

    private Configuration config;

    private HttpClient client;
    private HttpContext httpContext;

    private static final int HTTP_SUCCESS = 200;
    private static final int HTTP_FORBIDDEN = 403;
    private static final int HTTP_NOT_FOUND = 404;

    private SimpleDateFormat dateFormat;

    @Inject
    public PageTurnerWebProgressService(Context context, Configuration config, HttpClient client) {
        this.httpContext = new BasicHttpContext();
        this.config = config;
        this.client = client;

        this.dateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        // explicitly set timezone of input if needed
        dateFormat.setTimeZone(java.util.TimeZone.getTimeZone("Zulu"));
    }

    @Override
    public List<BookProgress> getProgress(String fileName) throws AccessException {

        String userId = this.config.getSynchronizationEmail();
        String accessKey = this.config.getSynchronizationAccessKey();

        if ("".equals(userId) || "".equals(fileName)) {
            LOG.debug("Empty username or filename. Aborting sync. (" + userId + " / " + fileName + ")");
            return null;
        }

        String key = computeKey(fileName);

        LOG.debug("Doing progress query for key: " + key);

        HttpGet get = new HttpGet(getSyncServerURL() + key + "?accessKey=" + URLEncoder.encode(accessKey));
        get.setHeader("User-Agent", config.getUserAgent());

        try {
            HttpResponse response = client.execute(get);

            int statusCode = response.getStatusLine().getStatusCode();
            LOG.debug("Got status " + statusCode + " from server.");

            if (statusCode == HTTP_FORBIDDEN) {
                throw new AccessException(EntityUtils.toString(response.getEntity()));
            }

            if (statusCode == HTTP_NOT_FOUND) {
                return new ArrayList<BookProgress>();
            }

            if (statusCode != HTTP_SUCCESS) {
                return null;
            }

            String responseString = EntityUtils.toString(response.getEntity());

            JSONArray jsonArray = new JSONArray(responseString);

            List<BookProgress> result = new ArrayList<BookProgress>();

            for (int i = 0; i < jsonArray.length(); i++) {

                JSONObject json = jsonArray.getJSONObject(i);

                int index = json.getInt("bookIndex");
                int progress = json.getInt("progress");
                int percentage = json.getInt("percentage");

                Date timeStamp = dateFormat.parse(json.getString("storedOn"));

                String deviceName = json.getString("deviceName");

                result.add(new BookProgress(fileName, index, progress, percentage, timeStamp, deviceName));
            }

            return result;

        } catch (IOException e) {
            LOG.error("Got error while querying server", e);
            return null;
        } catch (JSONException json) {
            LOG.error("Error reading response", json);
            return null;
        } catch (ParseException p) {
            LOG.error("Invalid date", p);
            return null;
        }

    }

    @Override
    public void storeProgress(String fileName, int index, int progress, int percentage) {

        if (!config.isSyncEnabled()) {
            return;
        }

        String key = computeKey(fileName);

        HttpPost post = new HttpPost(getSyncServerURL() + key);

        String filePart = fileName;

        if (fileName.indexOf("/") != -1) {
            filePart = fileName.substring(fileName.lastIndexOf('/'));
        }

        try {

            List<NameValuePair> pairs = new ArrayList<NameValuePair>();
            pairs.add(new BasicNameValuePair("bookIndex", "" + index));
            pairs.add(new BasicNameValuePair("progress", "" + progress));
            pairs.add(new BasicNameValuePair("title", Integer.toHexString(filePart.hashCode())));
            pairs.add(new BasicNameValuePair("deviceName", this.config.getDeviceName()));
            pairs.add(new BasicNameValuePair("percentage", "" + percentage));
            pairs.add(new BasicNameValuePair("userId",
                    Integer.toHexString(this.config.getSynchronizationEmail().hashCode())));
            pairs.add(new BasicNameValuePair("accessKey", this.config.getSynchronizationAccessKey()));

            post.setEntity(new UrlEncodedFormEntity(pairs));
            post.setHeader("User-Agent", config.getUserAgent());

            HttpResponse response = client.execute(post, this.httpContext);

            if (response.getStatusLine().getStatusCode() == HTTP_FORBIDDEN) {
                throw new AccessException(EntityUtils.toString(response.getEntity()));
            }

            LOG.debug("Got status " + response.getStatusLine().getStatusCode() + " from server.");

        } catch (Exception io) {
            LOG.error("Got error while POSTing update:", io);
            //fail silently
        }

    }

    private String getSyncServerURL() {
        String url = config.getSyncServerURL();
        if (!url.endsWith("/")) {
            url = url + "/";
        }

        return url;
    }

    private String computeKey(String fileName) {

        String filePart = fileName;

        if (fileName.indexOf("/") != -1) {
            filePart = fileName.substring(fileName.lastIndexOf('/'));
        }

        String plainTextKey = this.config.getSynchronizationEmail() + ":" + filePart;

        String hash = Integer.toHexString(plainTextKey.hashCode());

        return hash;
    }
}