com.pursuer.reader.easyrss.network.SubscriptionDataSyncer.java Source code

Java tutorial

Introduction

Here is the source code for com.pursuer.reader.easyrss.network.SubscriptionDataSyncer.java

Source

/*******************************************************************************
 * Copyright (c) 2012 Pursuer (http://pursuer.me).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     Pursuer - initial API and implementation
 ******************************************************************************/

package com.pursuer.reader.easyrss.network;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.fasterxml.jackson.core.JsonParseException;
import com.pursuer.reader.easyrss.R;
import com.pursuer.reader.easyrss.data.DataMgr;
import com.pursuer.reader.easyrss.data.GoogleAnalyticsMgr;
import com.pursuer.reader.easyrss.data.Setting;
import com.pursuer.reader.easyrss.data.Subscription;
import com.pursuer.reader.easyrss.data.parser.OnSubscriptionRetrievedListener;
import com.pursuer.reader.easyrss.data.parser.SubscriptionJSONParser;
import com.pursuer.reader.easyrss.data.readersetting.SettingSyncInterval;
import com.pursuer.reader.easyrss.data.readersetting.SettingSyncMethod;
import com.pursuer.reader.easyrss.network.url.SubscriptionIconUrl;
import com.pursuer.reader.easyrss.network.url.SubscriptionListURL;

public class SubscriptionDataSyncer extends AbsDataSyncer {
    private class SyncerSubscriptionListener implements OnSubscriptionRetrievedListener {
        final private List<Subscription> subscriptions;

        public SyncerSubscriptionListener() {
            this.subscriptions = new LinkedList<Subscription>();
        }

        public List<Subscription> getSubscriptions() {
            return subscriptions;
        }

        public void onSubscriptionRetrieved(final Subscription sub) {
            subscriptions.add(sub);
        }
    }

    private static SubscriptionDataSyncer instance;

    private static synchronized void clearInstance() {
        instance = null;
    }

    public static synchronized SubscriptionDataSyncer getInstance(final DataMgr dataMgr, final int networkConfig) {
        if (instance == null) {
            instance = new SubscriptionDataSyncer(dataMgr, networkConfig);
        }
        return instance;
    }

    public static synchronized boolean hasInstance() {
        return instance != null;
    }

    private SubscriptionDataSyncer(final DataMgr dataMgr, final int networkConfig) {
        super(dataMgr, networkConfig);
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        } else {
            return (obj instanceof SubscriptionDataSyncer);
        }
    }

    @Override
    protected void finishSyncing() {
        clearInstance();
    }

    @Override
    public void startSyncing() throws DataSyncerException {
        final String sExpTime = dataMgr.getSettingByName(Setting.SETTING_SUBSCRIPTION_LIST_EXPIRE_TIME);
        if (networkConfig != SettingSyncMethod.SYNC_METHOD_MANUAL && sExpTime != null
                && Long.valueOf(sExpTime) + new SettingSyncInterval(dataMgr).toSeconds() * 1000
                        - 10 * 60 * 1000 > System.currentTimeMillis()) {
            return;
        }

        syncSubscriptions();
        syncSubscriptionIcons();

        dataMgr.updateSetting(
                new Setting(Setting.SETTING_SUBSCRIPTION_LIST_EXPIRE_TIME, System.currentTimeMillis()));
    }

    private void syncSubscriptionIcons() throws DataSyncerException {
        final Context context = dataMgr.getContext();
        if (!NetworkUtils.checkSyncingNetworkStatus(context, networkConfig)) {
            return;
        }
        final ContentResolver resolver = context.getContentResolver();
        final Cursor cur = resolver.query(Subscription.CONTENT_URI,
                new String[] { Subscription._UID, Subscription._ICON, Subscription._URL }, null, null, null);
        for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
            final String uid = cur.getString(0);
            final byte[] data = cur.getBlob(1);
            final String subUrl = cur.getString(2);
            if (subUrl != null && data == null) {
                final SubscriptionIconUrl fetchUrl = new SubscriptionIconUrl(isHttpsConnection, subUrl);
                try {
                    final byte[] iconData = httpGetQueryByte(fetchUrl);
                    final Bitmap icon = BitmapFactory.decodeByteArray(iconData, 0, iconData.length);
                    final int size = icon.getWidth() * icon.getHeight() * 2;
                    final ByteArrayOutputStream output = new ByteArrayOutputStream(size);
                    icon.compress(Bitmap.CompressFormat.PNG, 100, output);
                    output.flush();
                    output.close();
                    dataMgr.updateSubscriptionIconByUid(uid, output.toByteArray());
                } catch (final IOException exception) {
                    cur.close();
                    throw new DataSyncerException(exception);
                }
            }
        }
        cur.close();
    }

    private void syncSubscriptions() throws DataSyncerException {
        final Context context = dataMgr.getContext();
        if (!NetworkUtils.checkSyncingNetworkStatus(context, networkConfig)) {
            return;
        }
        notifyProgressChanged(context.getString(R.string.TxtSyncingSubscriptions), -1, -1);

        final InputStream stream = httpGetQueryStream(new SubscriptionListURL(isHttpsConnection));
        final SubscriptionJSONParser parser = new SubscriptionJSONParser(stream);
        final long curTime = System.currentTimeMillis();
        try {
            final SyncerSubscriptionListener listener = new SyncerSubscriptionListener();
            parser.parse(listener);
            dataMgr.addSubscriptions(listener.getSubscriptions());
            final int sAll = listener.getSubscriptions().size();
            final int sAllRange = sAll / 10 * 10;
            GoogleAnalyticsMgr.getInstance().trackEvent(GoogleAnalyticsMgr.CATEGORY_SYNCING,
                    GoogleAnalyticsMgr.ACTION_SYNCING_SUBSCRIPTIONS, sAllRange + "-" + (sAllRange + 9), sAll);
        } catch (final JsonParseException exception) {
            throw new DataSyncerException(exception);
        } catch (final IllegalStateException exception) {
            throw new DataSyncerException(exception);
        } catch (final IOException exception) {
            throw new DataSyncerException(exception);
        } finally {
            try {
                stream.close();
            } catch (final IOException exception) {
                exception.printStackTrace();
            }
        }
        dataMgr.removeOutdatedSubscriptions(curTime);
    }
}