biz.varkon.shelvesom.server.CVInfo.java Source code

Java tutorial

Introduction

Here is the source code for biz.varkon.shelvesom.server.CVInfo.java

Source

/*
 * Copyright (C) 2010 Garen J. Torikian
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package biz.varkon.shelvesom.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.net.Uri;
import android.util.Xml;
import android.view.InflateException;

import biz.varkon.shelvesom.provider.books.BooksStore;
import biz.varkon.shelvesom.util.CookieStore;
import biz.varkon.shelvesom.util.HttpManager;
import biz.varkon.shelvesom.util.IOUtilities;
import biz.varkon.shelvesom.util.ImageUtilities;
import biz.varkon.shelvesom.util.IOUtilities.inputTypes;
import biz.varkon.shelvesom.util.ImageUtilities.ExpiringBitmap;

public class CVInfo {
    public static final String NAME = "5h3lv35";

    protected static final String DETAILS = "http://api.comicvine.com/issue/";
    protected static final String REST_HOST = "api.comicvine.com";
    protected static final String REST_SEARCH_PATH = "/search/";
    protected static final String REST_RETRIEVE_PATH = "/issue/";
    protected static final String REST_CHARACTER_PATH = "/character/";

    protected static final String API_KEY = "api_key";
    protected static final String apiKey = "d243eede6261fefe52b0030094b5bafcd3e2e7fa";
    protected static final String QUERY = "query";
    protected static final String RESOURCES = "resources";
    protected static final String OFFSET = "offset";

    protected static final String RESPONSE_TAG_RESULTS = "results";
    protected static final String RESPONSE_TAG_ISSUE = "issue";
    protected static final String RESPONSE_TAG_URL = "URL";
    protected static final String RESPONSE_TAG_NAME = "name";

    protected static final String PRIMARY_NAME = "primary";
    protected static final String RESPONSE_TAG_TYPE = "Type";

    protected static final String RESPONSE_TAG_ID = "id";
    protected static final String RESPONSE_TAG_IMAGESET = "super_url";
    protected static final String RESPONSE_TAG_DESCRIPTION = "description";
    protected static final String RESPONSE_TAG_DETAILPAGEURL = "site_detail_url";
    protected static final String RESPONSE_TAG_ISSUENUMBER = "issue_number";
    protected static final String RESPONSE_TAG_DAYPUBLISHED = "publish_day";
    protected static final String RESPONSE_TAG_MONTHPUBLISHED = "publish_month";
    protected static final String RESPONSE_TAG_YEARPUBLISHED = "publish_year";
    protected static final String RESPONSE_TAG_CHARACTER_CREDITS = "character_credits";
    protected static final String RESPONSE_TAG_CHARACTER = "character";
    protected static final String RESPONSE_TAG_PERSON_CREDITS = "person_credits";
    protected static final String RESPONSE_TAG_PERSON = "person";
    protected static final String RESPONSE_TAG_ROLES = "roles";
    protected static final String RESPONSE_TAG_ROLE = "role";

    private static final String LOG_TAG = "CVInfo";

    // GJT: Fields common to all derivatives
    protected static String mStoreName;
    protected String mStoreLabel;
    protected static String mHost;
    protected CVImageLoader mLoader;

    protected CVInfo() {
    }

    public static class CVImageLoader {
        public ImageUtilities.ExpiringBitmap load(String url) {
            final String cookie = CookieStore.get().getCookie(url);
            return ImageUtilities.load(url, cookie);
        }
    }

    protected static String getName() {
        return mStoreName;
    }

    public String getLabel() {
        return mStoreLabel;
    }

    /**
     * Constructs the query used to search for an item. The query can be any
     * combination of keywords. The store is free to interpret the keywords in
     * any way.
     * 
     * @param query
     *            A free form text query to search for item.
     * 
     * @return The Uri to the list of item matching the query.
     */

    public static Uri.Builder buildSearchQuery(String query, String page) {
        final Uri.Builder builder = new Uri.Builder();

        builder.path(REST_SEARCH_PATH);
        builder.appendQueryParameter(API_KEY, apiKey);
        builder.appendQueryParameter(QUERY, query);
        builder.appendQueryParameter(RESOURCES, RESPONSE_TAG_ISSUE);
        builder.appendQueryParameter(OFFSET, page);

        return builder;
    }

    public static Uri.Builder buildFindQuery(String query) {
        final Uri.Builder builder = new Uri.Builder();

        builder.path(REST_RETRIEVE_PATH);
        builder.appendPath(query);
        builder.appendPath("");
        builder.appendQueryParameter(API_KEY, apiKey);

        return builder;
    }

    public static Uri.Builder buildGetPublisherQuery(String id) {
        final Uri.Builder builder = new Uri.Builder();

        builder.path(REST_CHARACTER_PATH);
        builder.appendPath(id);
        builder.appendPath("");
        builder.appendQueryParameter(API_KEY, apiKey);
        builder.appendQueryParameter("format", "json");
        builder.appendQueryParameter("field_list", "publisher");

        return builder;
    }

    /**
     * Executes an HTTP request on a REST web service. If the response is ok,
     * the content is sent to the specified response handler.
     * 
     * @param host
     * @param get
     *            The GET request to executed.
     * @param handler
     *            The handler which will parse the response.
     * 
     * @throws java.io.IOException
     */
    protected void executeRequest(HttpHost host, HttpGet get, ResponseHandler handler) throws IOException {

        HttpEntity entity = null;
        try {
            final HttpResponse response = HttpManager.execute(host, get);
            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY || statusCode == HttpStatus.SC_SEE_OTHER) {
                Header header = response.getFirstHeader("Location");
                if (header != null) {
                    String redirectURI = header.getValue();
                    if ((redirectURI != null) && (!redirectURI.equals(""))) {
                        android.util.Log.e(LOG_TAG, "Redirect target: " + redirectURI);
                        DefaultHttpClient httpclient = new DefaultHttpClient();
                        get = new HttpGet(redirectURI);
                        entity = httpclient.execute(get).getEntity();
                        final InputStream in = entity.getContent();
                        handler.handleResponse(in);
                    }
                } else {
                    android.util.Log.e(LOG_TAG, "Invalid redirect");
                }
            } else if (statusCode == HttpStatus.SC_OK) {
                entity = response.getEntity();
                final InputStream in = entity.getContent();
                handler.handleResponse(in);
            }
        } finally {
            if (entity != null) {
                entity.consumeContent();
            }
        }
    }

    /**
     * Parses a valid XML response from the specified input stream. This method
     * must invoke parse
     * {@link ResponseParser#parseResponse(org.xmlpull.v1.XmlPullParser)} if the
     * XML response is valid, or throw an exception if it is not.
     * 
     * @param in
     *            The input stream containing the response sent by the web
     *            service.
     * @param responseParser
     *            The parser to use when the response is valid.
     * 
     * @throws java.io.IOException
     */
    public static void parseResponse(InputStream in, ResponseParser responseParser,
            IOUtilities.inputTypes inputType) throws IOException {
        final XmlPullParser parser = Xml.newPullParser();
        try {
            parser.setInput(new InputStreamReader(in));

            int type;
            while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
                // Empty
            }

            if (type != XmlPullParser.START_TAG) {
                throw new InflateException(parser.getPositionDescription() + ": No start tag found!");
            }

            String name;
            boolean valid = false;
            final int topDepth = parser.getDepth();

            while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > topDepth)
                    && type != XmlPullParser.END_DOCUMENT) {

                if (type != XmlPullParser.START_TAG) {
                    continue;
                }

                name = parser.getName();

                if (RESPONSE_TAG_RESULTS.equals(name)) {
                    valid = true;
                    break;
                }
            }

            if (valid)
                responseParser.parseResponse(parser);

        } catch (XmlPullParserException e) {
            final IOException ioe = new IOException("Could not parse the response");
            ioe.initCause(e);
            throw ioe;
        }
    }

    /**
     * Finds the next item entry in the XML input stream.
     * 
     * @param parser
     *            The XML parser to use to parse the item.
     * 
     * @return True if an item was found, false otherwise.
     */
    protected boolean findNextItem(XmlPullParser parser) throws XmlPullParserException, IOException {
        if (RESPONSE_TAG_ISSUE.equals(parser.getName())) {
            return true;
        }

        int type;
        final int depth = parser.getDepth();

        while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
                && type != XmlPullParser.END_DOCUMENT) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            if (RESPONSE_TAG_ISSUE.equals(parser.getName())) {
                return true;
            }
        }

        return false;
    }

    /**
     * Response handler used with
     * {@link BooksStore#executeRequest(org.apache.http.HttpHost, org.apache.http.client.methods.HttpGet, BooksStore.ResponseHandler)}
     * . The handler is invoked when a response is sent by the server. The
     * response is made available as an input stream.
     */
    public static interface ResponseHandler {
        /**
         * Processes the responses sent by the HTTP server following a GET
         * request.
         * 
         * @param in
         *            The stream containing the server's response.
         * 
         * @throws java.io.IOException
         */
        public void handleResponse(InputStream in) throws IOException;
    }

    /**
     * Response parser. When the request returns a valid response, this parser
     * is invoked to process the XML response.
     */
    public static interface ResponseParser {
        /**
         * Processes the XML response sent by the web service after a successful
         * request.
         * 
         * @param parser
         *            The parser containing the XML responses.
         * 
         * @throws org.xmlpull.v1.XmlPullParserException
         * @throws java.io.IOException
         */
        public void parseResponse(XmlPullParser parser) throws XmlPullParserException, IOException;
    }
}