de.dan_nrw.android.followerstat.dao.folllowers.TwitterFollowerDAO.java Source code

Java tutorial

Introduction

Here is the source code for de.dan_nrw.android.followerstat.dao.folllowers.TwitterFollowerDAO.java

Source

/* 
 * AndFollowerStat
 * 
 * Copyright (C) 2009  Daniel Czerwonk <d.czerwonk@googlemail.com>
 * 
 * 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 de.dan_nrw.android.followerstat.dao.folllowers;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.exception.OAuthException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.signature.SignatureMethod;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;

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

import com.google.inject.Inject;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import de.dan_nrw.android.followerstat.Follower;

/**
 * @author Daniel Czerwonk
 *
 */
public final class TwitterFollowerDAO implements ITwitterFollowerDAO {

    private static final int MAX_RETRIES = 10;
    private final OAuthConsumer consumer;

    /**
      * Creates a new instance of TwitterFollowerDAO.
      */
    @Inject
    TwitterFollowerDAO(TwitterOauthTokenData tokenData) {
        super();

        this.consumer = new CommonsHttpOAuthConsumer("VapPZ17tZjKE27elHRkc5g", // Application consumer key
                "M06hUmfajEp9wKOm5i9HlTxQxi4iSLPhUfWkRp2AkyY", // Application consumer key secret
                SignatureMethod.HMAC_SHA1);

        this.consumer.setTokenWithSecret(tokenData.getToken(), tokenData.getTokenSecret());
    }

    /**
     * Creates a new instance of TwitterFollowerDAO
     * @param tokenData
     * @return
     */
    public static ITwitterFollowerDAO createInstance(TwitterOauthTokenData tokenData) {
        return new TwitterFollowerDAO(tokenData);
    }

    /* (non-Javadoc)
      * @see de.dan_nrw.android.followerstat.dao.ITwitterFollowerDAO#getFollowerCount(java.lang.String)
      */
    @Override
    public long getFollowerCount(String userName)
            throws TwitterUserAccountNotFoundException, TwitterRequestException {
        try {
            String json = this.sendRequest(
                    URI.create(String.format("http://twitter.com/users/show/%s.json", userName)),
                    new StringResponseHandler(), true);

            JSONObject jsonObject = new JSONObject(json);

            return jsonObject.getLong("followers_count");
        } catch (ClientProtocolException ex) {
            throw new TwitterRequestException(ex);
        } catch (SecurityException ex) {
            throw new TwitterAuthException(ex.getCause());
        } catch (IOException ex) {
            if (ex.getMessage().equals("404")) {
                throw new TwitterUserAccountNotFoundException();
            }

            throw new TwitterRequestException(ex);
        } catch (JSONException ex) {
            throw new TwitterResponseParsingException(ex);
        } catch (OAuthExpectationFailedException ex) {
            throw new TwitterAuthException(ex);
        } catch (OAuthException ex) {
            throw new TwitterAuthException(ex);
        }
    }

    /* (non-Javadoc)
      * @see de.dan_nrw.android.followerstat.dao.folllowers.ITwitterFollowerDAO#getFollowers(java.lang.String)
      */
    @Override
    public Follower[] getFollowers(String userName)
            throws TwitterUserAccountNotFoundException, TwitterRequestException {
        try {
            String json = this.sendRequest(
                    URI.create(String.format("http://twitter.com/statuses/followers/%s.json", userName)),
                    new StringResponseHandler(), true);

            JSONArray jsonArray = new JSONArray(json);

            List<Follower> followers = new ArrayList<Follower>();

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

                followers.add(new Follower(jsonObject.getString("screen_name"),
                        URI.create(jsonObject.getString("profile_image_url"))));
            }

            return followers.toArray(new Follower[followers.size()]);
        } catch (ClientProtocolException ex) {
            throw new TwitterRequestException(ex);
        } catch (SecurityException ex) {
            throw new TwitterAuthException(ex.getCause());
        } catch (IOException ex) {
            if (ex.getMessage().equals("404")) {
                throw new TwitterUserAccountNotFoundException();
            }

            throw new TwitterRequestException(ex);
        } catch (JSONException ex) {
            throw new TwitterResponseParsingException(ex);
        } catch (OAuthExpectationFailedException ex) {
            throw new TwitterAuthException(ex);
        } catch (OAuthException ex) {
            throw new TwitterAuthException(ex);
        }
    }

    /* (non-Javadoc)
      * @see de.dan_nrw.android.followerstat.dao.folllowers.ITwitterFollowerDAO#getFollowerImage(de.dan_nrw.android.followerstat.Follower)
      */
    @Override
    public Bitmap getFollowerImage(Follower follower) throws TwitterRequestException {
        try {
            return this.sendRequest(follower.getImageUri(), new BitmapResponseHandler(), false);
        } catch (ClientProtocolException ex) {
            throw new TwitterRequestException(ex);
        } catch (IOException ex) {
            throw new TwitterRequestException(ex);
        } catch (OAuthExpectationFailedException ex) {
            throw new TwitterAuthException(ex);
        } catch (OAuthException ex) {
            throw new TwitterAuthException(ex);
        }
    }

    private <T> T sendRequest(URI uri, ResponseHandler<T> responseHandler, boolean requiresAuth)
            throws ClientProtocolException, IOException, OAuthException, OAuthExpectationFailedException {
        DefaultHttpClient client = new DefaultHttpClient();
        client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(MAX_RETRIES, true));

        HttpGet request = new HttpGet(uri);

        if (requiresAuth) {
            this.consumer.sign(request);
        }

        return client.execute(request, responseHandler);
    }

    private static class BitmapResponseHandler implements ResponseHandler<Bitmap> {

        /* (non-Javadoc)
           * @see org.apache.http.client.ResponseHandler#handleResponse(org.apache.http.HttpResponse)
           */
        @Override
        public Bitmap handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode >= 300) {
                if (statusCode == 401) {
                    throw new SecurityException();
                }

                throw new IOException(Integer.toString(response.getStatusLine().getStatusCode()));
            }

            return BitmapFactory.decodeStream(new BufferedInputStream(response.getEntity().getContent()));
        }
    }

    private static class StringResponseHandler implements ResponseHandler<String> {

        /* (non-Javadoc)
           * @see org.apache.http.client.ResponseHandler#handleResponse(org.apache.http.HttpResponse)
           */
        @Override
        public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode >= 300) {
                if (statusCode == 401) {
                    throw new SecurityException();
                }

                throw new IOException(Integer.toString(response.getStatusLine().getStatusCode()));
            }

            BufferedReader reader = null;

            try {
                reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

                char[] buffer = new char[1024];
                int charsRead = 0;
                StringBuilder stringBuilder = new StringBuilder();

                while ((charsRead = reader.read(buffer)) > 0) {
                    stringBuilder.append(buffer, 0, charsRead);
                }

                return stringBuilder.toString();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException ex) {
                        // exception could hide exception thrown in try block
                    }
                }
            }
        }
    }
}