com.flicklib.service.HttpClientSourceLoader.java Source code

Java tutorial

Introduction

Here is the source code for com.flicklib.service.HttpClientSourceLoader.java

Source

/*
 * This file is part of Flicklib.
 *
 * Copyright (C) Zsombor Gegesy
 *
 * 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 com.flicklib.service;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
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.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.google.inject.name.Named;

public class HttpClientSourceLoader implements SourceLoader {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientSourceLoader.class);

    private final DefaultHttpClient client;

    @Inject
    public HttpClientSourceLoader(@Named(value = Constants.HTTP_TIMEOUT) final Integer timeout) {

        ThreadSafeClientConnManager tm = new ThreadSafeClientConnManager();
        tm.setDefaultMaxPerRoute(20);
        tm.setMaxTotal(200);
        client = new DefaultHttpClient(tm);

        if (timeout != null) {
            // wait max x sec
            HttpConnectionParams.setSoTimeout(client.getParams(), timeout);
        }
    }

    @Override
    public Source loadSource(String url) throws IOException {
        HttpResponse response = null;
        try {
            LOGGER.info("Loading " + url);
            HttpGet httpMethod = new HttpGet(url);
            //httpMethod.addRequestHeader("Content-Type","text/html; charset=UTF-8");
            HttpContext ctx = new BasicHttpContext();
            response = client.execute(httpMethod, ctx);

            return buildSource(url, response, httpMethod, ctx);
        } finally {
            if (response != null) {
                EntityUtils.consume(response.getEntity());
            }
        }
    }

    @Override
    public Source loadSource(String url, boolean useCache) throws IOException {
        return loadSource(url);
    }

    @Override
    public Source post(String url, Map<String, String> parameters, Map<String, String> headers) throws IOException {
        HttpResponse response = null;
        try {
            LOGGER.info("Loading " + url);
            HttpPost httpMethod = new HttpPost(url);
            if (parameters != null && !parameters.isEmpty()) {
                List<NameValuePair> formparams = new ArrayList<NameValuePair>();
                for (Entry<String, String> entry : parameters.entrySet()) {
                    formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8");
                httpMethod.setEntity(form);
            }
            if (headers != null && !headers.isEmpty()) {
                for (Entry<String, String> entry : headers.entrySet()) {
                    httpMethod.addHeader(entry.getKey(), entry.getValue());
                }
            }
            HttpContext ctx = new BasicHttpContext();
            response = client.execute(httpMethod, ctx);
            return buildSource(url, response, httpMethod, ctx);
        } finally {
            EntityUtils.consume(response.getEntity());
        }

    }

    @Override
    public RestBuilder url(final String url) {
        return new HttpClientRestBuilder(url);
    }

    private Source buildSource(String url, HttpResponse response, HttpRequestBase httpMethod, HttpContext ctx)
            throws IOException {
        LOGGER.info("Finished loading at " + httpMethod.getURI().toString());
        final HttpEntity entity = response.getEntity();
        String responseCharset = EntityUtils.getContentCharSet(entity);
        String contentType = EntityUtils.getContentMimeType(entity);
        LOGGER.info("Response charset = " + responseCharset);
        String content = EntityUtils.toString(entity);

        HttpUriRequest req = (HttpUriRequest) ctx.getAttribute(ExecutionContext.HTTP_REQUEST);
        HttpHost target = (HttpHost) ctx.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
        URI resultUri;
        try {
            resultUri = (target != null && req != null) ? new URI(target.toURI() + req.getURI().toString())
                    : httpMethod.getURI();
        } catch (URISyntaxException e) {
            e.printStackTrace();
            resultUri = httpMethod.getURI();
        }
        // String contentType = URLConnection.guessContentTypeFromName(url)
        return new Source(resultUri.toString(), content, contentType, url);
    }

    private final class HttpClientRestBuilder implements RestBuilder {

        private final List<Header> headers = new ArrayList<Header>();
        private final String url;

        public HttpClientRestBuilder(final String url) {
            this.url = url;
        }

        @Override
        public RestBuilder setHeader(String name, String value) {
            headers.add(new Header(name, value));
            return this;
        }

        @Override
        public RestResult get() throws IOException {
            HttpGet httpMethod = new HttpGet(url);
            for (Header header : headers) {
                httpMethod.addHeader(header.name, header.value);
            }
            HttpContext ctx = new BasicHttpContext();
            HttpResponse response = client.execute(httpMethod, ctx);
            return new HttpClientRestResult(response);
        }

    }

    private static final class Header {
        private final String name;
        private final String value;

        private Header(String name, String value) {
            super();
            this.name = name;
            this.value = value;
        }
    }

    private final class HttpClientRestResult implements RestResult {

        private final HttpResponse response;

        public HttpClientRestResult(final HttpResponse response) {
            this.response = response;
        }

        @Override
        public String getString() throws IOException {
            final HttpEntity entity = response.getEntity();
            String content = EntityUtils.toString(entity);
            return content;
        }
    }
}