me.xiaopan.android.gohttp.HttpRequestHandler.java Source code

Java tutorial

Introduction

Here is the source code for me.xiaopan.android.gohttp.HttpRequestHandler.java

Source

/*
 * Copyright (C) 2013 Peng fei Pan <sky@xiaopan.me>
 * 
 * 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 me.xiaopan.android.gohttp;

import android.util.Log;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.entity.FileEntity;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Http?
 */
public class HttpRequestHandler implements Runnable {
    private HttpRequest httpRequest;

    public HttpRequestHandler(HttpRequest httpRequest) {
        this.httpRequest = httpRequest;
    }

    @Override
    public void run() {
        if (httpRequest.isCanceled()) {
            httpRequest.finish();
            new CancelRunnable(httpRequest).execute();
            if (httpRequest.getGoHttp().isDebugMode())
                Log.w(GoHttp.LOG_TAG,
                        httpRequest.getName() + "; " + "Canceled : " + "; " + httpRequest.getUrl());
            return;
        }
        if (httpRequest.getGoHttp().isDebugMode())
            Log.d(GoHttp.LOG_TAG,
                    httpRequest.getName() + "; " + "Started : " + "; " + httpRequest.getUrl());

        boolean isCache = httpRequest.getCacheConfig() != null;
        ReentrantLock reentrantLock = null;

        if (isCache) {
            reentrantLock = httpRequest.getGoHttp().getSyncManager()
                    .getLockByCacheId(httpRequest.getCacheConfig().getId());
            reentrantLock.lock();

            if (httpRequest.isCanceled()) {
                httpRequest.finish();
                new CancelRunnable(httpRequest).execute();
                if (httpRequest.getGoHttp().isDebugMode())
                    Log.w(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Canceled : ??" + "; "
                            + httpRequest.getUrl());
                reentrantLock.unlock();
                return;
            }
        }

        boolean isRefreshCache = isCache && httpRequest.getCacheConfig().isRefreshCache();
        boolean isContinueCallback = true;
        HttpResponse httpResponse = null;

        // ??
        if (isCache && httpRequest.getGoHttp().getCacheManager().isHasAvailableCache(httpRequest)) {
            if (httpRequest.isCanceled()) {
                httpRequest.finish();
                new CancelRunnable(httpRequest).execute();
                if (httpRequest.getGoHttp().isDebugMode())
                    Log.w(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Canceled : ?" + "; "
                            + httpRequest.getUrl());
                reentrantLock.unlock();
                return;
            }
            if (httpRequest.getGoHttp().isDebugMode())
                Log.d(GoHttp.LOG_TAG,
                        httpRequest.getName() + "; " + "Cache : ?" + "; " + httpRequest.getUrl());

            // ?Http?
            httpResponse = httpRequest.getGoHttp().getCacheManager().readHttpResponseFromCache(httpRequest);
            if (httpRequest.isCanceled()) {
                httpRequest.finish();
                new CancelRunnable(httpRequest).execute();
                if (httpRequest.getGoHttp().isDebugMode())
                    Log.w(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Canceled : ?" + "; "
                            + httpRequest.getUrl());
                reentrantLock.unlock();
                return;
            }

            if (httpResponse != null) {
                try {
                    Object responseObject = httpRequest.getResponseHandler().handleResponse(httpRequest,
                            httpResponse);
                    if (responseObject == null) {
                        throw new Exception("response object is null");
                    }

                    // ???
                    isContinueCallback = isRefreshCache && httpRequest.getCacheConfig().isRefreshCallback();
                    if (!(responseObject instanceof HttpRequest.Failure)
                            && httpRequest.getResponseHandleCompletedAfterListener() != null) {
                        //noinspection unchecked
                        Object response = httpRequest.getResponseHandleCompletedAfterListener()
                                .onResponseHandleAfter(httpRequest, httpResponse, responseObject, true,
                                        isContinueCallback);
                        if (response != null) {
                            responseObject = response;
                        }
                    }
                    if (httpRequest.isCanceled()) {
                        httpRequest.finish();
                        new CancelRunnable(httpRequest).execute();
                        if (httpRequest.getGoHttp().isDebugMode())
                            Log.w(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Canceled : ??"
                                    + "; " + httpRequest.getUrl());
                        reentrantLock.unlock();
                        return;
                    }

                    // ?????
                    if (!isRefreshCache) {
                        httpRequest.finish();
                    }
                    if (responseObject instanceof HttpRequest.Failure) {
                        new FailedRunnable(httpRequest, httpResponse, (HttpRequest.Failure) responseObject, true,
                                isContinueCallback).execute();
                    } else {
                        new CompletedRunnable(httpRequest, httpResponse, responseObject, true, isContinueCallback)
                                .execute();
                    }
                    // ?????
                    if (!isRefreshCache) {
                        if (httpRequest.getGoHttp().isDebugMode())
                            Log.d(GoHttp.LOG_TAG,
                                    httpRequest.getName() + "; "
                                            + "Completed : ???" + "; "
                                            + httpRequest.getUrl());
                        reentrantLock.unlock();
                        return;
                    }
                    if (httpRequest.getGoHttp().isDebugMode())
                        Log.d(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Cache : ??"
                                + "; " + httpRequest.getUrl());
                } catch (Throwable e) {
                    e.printStackTrace();
                    if (httpRequest.isCanceled()) {
                        httpRequest.finish();
                        new CancelRunnable(httpRequest).execute();
                        if (httpRequest.getGoHttp().isDebugMode())
                            Log.w(GoHttp.LOG_TAG,
                                    httpRequest.getName() + "; "
                                            + "Canceled : ?Http??" + "; "
                                            + httpRequest.getUrl());
                        reentrantLock.unlock();
                        return;
                    }
                    if (httpRequest.getGoHttp().isDebugMode())
                        Log.e(GoHttp.LOG_TAG,
                                httpRequest.getName() + "; " + "Failed : ?Http??"
                                        + "; " + httpRequest.getUrl());

                    new FailedRunnable(httpRequest, httpResponse, new HttpRequest.Failure(e), true,
                            isContinueCallback).execute();
                }
            }
        }

        // ??
        try {
            httpResponse = httpRequest.getGoHttp().getNetManager().getHttpResponse(httpRequest);
        } catch (Throwable e) {
            e.printStackTrace();
            releaseConnect(httpResponse);
            httpRequest.finish();
            if (httpRequest.isCanceled()) {
                if (isContinueCallback) {
                    new CancelRunnable(httpRequest).execute();
                }
                if (httpRequest.getGoHttp().isDebugMode())
                    Log.w(GoHttp.LOG_TAG, httpRequest.getName() + "; "
                            + "Canceled : ?Http??" + "; " + httpRequest.getUrl());
                if (reentrantLock != null)
                    reentrantLock.unlock();
                return;
            }
            if (httpRequest.getGoHttp().isDebugMode())
                Log.e(GoHttp.LOG_TAG, httpRequest.getName() + "; "
                        + "Failed : ?Http??" + "; " + httpRequest.getUrl());

            if (isContinueCallback) {
                new FailedRunnable(httpRequest, httpResponse, new HttpRequest.Failure(e), false, false).execute();
            }
            if (reentrantLock != null)
                reentrantLock.unlock();
            return;
        }
        if (httpRequest.isCanceled()) {
            releaseConnect(httpResponse);
            httpRequest.finish();
            new CancelRunnable(httpRequest).execute();
            if (httpRequest.getGoHttp().isDebugMode())
                Log.w(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Canceled : ?Http?"
                        + "; " + httpRequest.getUrl());
            if (reentrantLock != null)
                reentrantLock.unlock();
            return;
        }
        if (httpRequest.getGoHttp().isDebugMode())
            Log.d(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Net : ?Http??" + "; "
                    + httpRequest.getUrl());

        // Http?
        if (isCache && httpRequest.getResponseHandler().canCache(httpResponse)) {
            try {
                httpRequest.getGoHttp().getCacheManager().saveHttpResponseToCache(httpRequest, httpResponse);
            } catch (IOException e) {
                e.printStackTrace();
                releaseConnect(httpResponse);
                httpRequest.finish();
                if (httpRequest.isCanceled()) {
                    if (isContinueCallback) {
                        new CancelRunnable(httpRequest).execute();
                    }
                    if (httpRequest.getGoHttp().isDebugMode())
                        Log.w(GoHttp.LOG_TAG, httpRequest.getName() + "; "
                                + "Canceled : Http??" + "; " + httpRequest.getUrl());
                    reentrantLock.unlock();
                    return;
                }
                if (httpRequest.getGoHttp().isDebugMode())
                    Log.d(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Failed : Http??"
                            + "; " + httpRequest.getUrl());
                if (isContinueCallback) {
                    new FailedRunnable(httpRequest, httpResponse, new HttpRequest.Failure(e), false, false)
                            .execute();
                }
                reentrantLock.unlock();
                return;
            }
            if (httpRequest.isCanceled()) {
                httpRequest.finish();
                new CancelRunnable(httpRequest).execute();
                if (httpRequest.getGoHttp().isDebugMode())
                    Log.w(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Canceled : Http?" + "; "
                            + httpRequest.getUrl());
                reentrantLock.unlock();
                return;
            }
            if (httpRequest.getGoHttp().isDebugMode())
                Log.d(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Cache : Http??" + "; "
                        + httpRequest.getUrl());
        }

        // ???
        if (!isContinueCallback) {
            httpRequest.finish();
            if (httpRequest.getGoHttp().isDebugMode())
                Log.d(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Completed : ??" + "; "
                        + httpRequest.getUrl());
            reentrantLock.unlock();
            return;
        }

        // ??
        Object responseObject;
        try {
            responseObject = httpRequest.getResponseHandler().handleResponse(httpRequest, httpResponse);
            if (responseObject == null) {
                throw new Exception("response object is null");
            }

            // ???
            if (!(responseObject instanceof HttpRequest.Failure)
                    && httpRequest.getResponseHandleCompletedAfterListener() != null) {
                //noinspection unchecked
                Object response = httpRequest.getResponseHandleCompletedAfterListener()
                        .onResponseHandleAfter(httpRequest, httpResponse, responseObject, false, false);
                if (response != null) {
                    responseObject = response;
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
            releaseConnect(httpResponse);
            httpRequest.finish();

            if (httpRequest.isCanceled()) {
                new CancelRunnable(httpRequest).execute();
                if (httpRequest.getGoHttp().isDebugMode())
                    Log.w(GoHttp.LOG_TAG,
                            httpRequest.getName() + "; "
                                    + "Canceled : ??Http??" + "; "
                                    + httpRequest.getUrl());
                if (reentrantLock != null)
                    reentrantLock.unlock();
                return;
            }
            if (httpRequest.getGoHttp().isDebugMode())
                Log.e(GoHttp.LOG_TAG,
                        httpRequest.getName() + "; " + "Failed : ??Http??"
                                + "; " + httpRequest.getUrl());

            new FailedRunnable(httpRequest, httpResponse, new HttpRequest.Failure(e), false, false).execute();
            if (reentrantLock != null)
                reentrantLock.unlock();
            return;
        }
        if (httpRequest.isCanceled()) {
            releaseConnect(httpResponse);
            httpRequest.finish();
            new CancelRunnable(httpRequest).execute();
            if (httpRequest.getGoHttp().isDebugMode())
                Log.w(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Canceled : ?Http?" + "; "
                        + httpRequest.getUrl());
            if (reentrantLock != null)
                reentrantLock.unlock();
            return;
        }
        if (httpRequest.getGoHttp().isDebugMode())
            Log.d(GoHttp.LOG_TAG,
                    httpRequest.getName() + "; " + "Net : ?Http?" + "; " + httpRequest.getUrl());

        // 
        if (responseObject instanceof HttpRequest.Failure) {
            HttpRequest.Failure failure = (HttpRequest.Failure) responseObject;
            new FailedRunnable(httpRequest, httpResponse, failure, false, false).execute();
            if (httpRequest.getGoHttp().isDebugMode())
                Log.e(GoHttp.LOG_TAG, httpRequest.getName() + "; " + "Failed : " + failure.toString() + "; "
                        + httpRequest.getUrl());
        } else {
            new CompletedRunnable(httpRequest, httpResponse, responseObject, false, false).execute();
            if (httpRequest.getGoHttp().isDebugMode())
                Log.d(GoHttp.LOG_TAG,
                        httpRequest.getName() + "; " + "Completed : ?" + "; " + httpRequest.getUrl());
        }
        httpRequest.finish();
        if (reentrantLock != null)
            reentrantLock.unlock();
    }

    public static void releaseConnect(HttpResponse httpResponse) {
        if (httpResponse == null) {
            return;
        }

        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity == null || httpEntity instanceof FileEntity) {
            return;
        }

        InputStream inputStream = null;
        try {
            inputStream = httpEntity.getContent();
        } catch (IOException e) {
            //            e.printStackTrace();
        }
        if (inputStream == null) {
            return;
        }

        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static class CancelRunnable implements Runnable {
        private HttpRequest httpRequest;

        public CancelRunnable(HttpRequest httpRequest) {
            this.httpRequest = httpRequest;
        }

        @Override
        public void run() {
            httpRequest.getListener().onCanceled(httpRequest);
        }

        public void execute() {
            httpRequest.getGoHttp().getHandler().post(this);
        }
    }

    public static class FailedRunnable implements Runnable {
        private HttpRequest httpRequest;
        private HttpResponse httpResponse;
        private HttpRequest.Failure failure;
        private boolean isCache;
        private boolean isContinueCallback;

        public FailedRunnable(HttpRequest httpRequest, HttpResponse httpResponse, HttpRequest.Failure failure,
                boolean isCache, boolean isContinueCallback) {
            this.httpRequest = httpRequest;
            this.httpResponse = httpResponse;
            this.failure = failure;
            this.isCache = isCache;
            this.isContinueCallback = isContinueCallback;
        }

        @Override
        public void run() {
            if (httpRequest.isCanceled()) {
                return;
            }

            httpRequest.getListener().onFailed(httpRequest, httpResponse, failure, isCache, isContinueCallback);
        }

        public void execute() {
            httpRequest.getGoHttp().getHandler().post(this);
        }
    }

    public static class CompletedRunnable implements Runnable {
        private HttpRequest httpRequest;
        private HttpResponse httpResponse;
        private Object responseObject;
        private boolean isCache;
        private boolean isContinueCallback;

        public CompletedRunnable(HttpRequest httpRequest, HttpResponse httpResponse, Object responseObject,
                boolean isCache, boolean isContinueCallback) {
            this.httpRequest = httpRequest;
            this.httpResponse = httpResponse;
            this.responseObject = responseObject;
            this.isCache = isCache;
            this.isContinueCallback = isContinueCallback;
        }

        @Override
        public void run() {
            if (httpRequest.isCanceled()) {
                return;
            }

            //noinspection unchecked
            httpRequest.getListener().onCompleted(httpRequest, httpResponse, responseObject, isCache,
                    isContinueCallback);
        }

        public void execute() {
            httpRequest.getGoHttp().getHandler().post(this);
        }
    }

    public static class UpdateProgressRunnable implements Runnable {
        private HttpRequest httpRequest;
        private long totalLength;
        private long completedLength;

        public UpdateProgressRunnable(HttpRequest httpRequest, long totalLength, long completedLength) {
            this.httpRequest = httpRequest;
            this.totalLength = totalLength;
            this.completedLength = completedLength;
        }

        @Override
        public void run() {
            if (httpRequest.isCanceled()) {
                return;
            }

            httpRequest.getProgressListener().onUpdateProgress(httpRequest, totalLength, completedLength);
        }

        public void execute() {
            httpRequest.getGoHttp().getHandler().post(this);
        }
    }
}