fr.eyal.lib.data.service.DataLibService.java Source code

Java tutorial

Introduction

Here is the source code for fr.eyal.lib.data.service.DataLibService.java

Source

/*
 * Copyright (C) 2012 Eyal LEZMY (http://www.eyal.fr)
 *
 * 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 fr.eyal.lib.data.service;

import java.util.ArrayList;
import java.util.HashMap;

import org.apache.http.Header;
import org.apache.http.client.CookieStore;
import org.apache.http.cookie.CookieSpecRegistry;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.util.Log;
import fr.eyal.lib.data.model.BusinessObjectDAO;
import fr.eyal.lib.data.model.ResponseBusinessObjectDAO;
import fr.eyal.lib.data.processor.ProcessorResponseHandler;
import fr.eyal.lib.data.service.model.BusinessResponse;
import fr.eyal.lib.data.service.model.ComplexOptions;
import fr.eyal.lib.data.service.model.DataLibRequest;
import fr.eyal.lib.data.service.model.DataLibResponse;
import fr.eyal.lib.service.MultiThreadService;
import fr.eyal.lib.util.FileManager;
import fr.eyal.lib.util.Out;

@TargetApi(Build.VERSION_CODES.CUPCAKE)
public abstract class DataLibService extends MultiThreadService implements ProcessorResponseHandler {

    private static final String TAG = "DataLibService";

    protected static final int MAX_THREADS = 3;

    //different Service's possible actions
    public static final int COOKIES_FLUSH = 999999999;

    //different information recieved by the Service
    /**
     * Intext extra content : Webservice type
     */
    public static final String INTENT_EXTRA_PROCESSOR_TYPE = "processorType";
    /**
     * Intext extra content : Useragent to send
     */
    public static final String INTENT_EXTRA_USER_AGENT = "userAgent";
    /**
     * Intext extra content : Webservice URL
     */
    public static final String INTENT_EXTRA_URL = "url";
    /**
     * Intext extra content : parameters to send
     */
    public static final String INTENT_EXTRA_PARAMS = "params";
    /**
     * Intext extra content : Webservice path
     */
    public static final String INTENT_EXTRA_PATH = "path";
    /**
     * Intext extra content : web service data
     */
    public static final String INTENT_EXTRA_DATA = "data";
    /**
     * Intext extra content : content type
     */
    public static final String INTENT_EXTRA_CONTENT_TYPE = "contentType";
    /**
     * Intext extra content : options to add to the request
     */
    public static final String INTENT_EXTRA_REQUEST_OPTION = "optionRequest";
    /**
     * Intext extra content : parsing type of the response
     */
    public static final String INTENT_EXTRA_PARSE_TYPE = "parseType";
    /**
     * Intext extra content : complex option for the request
     */
    public static final String INTENT_EXTRA_COMPLEX_OPTIONS = "complexOptions";

    /**
     * title of the cookies' header
     */
    protected static final String COOKIE_HEADER_TITLE = "Set-Cookie";

    protected ArrayList<Header> mHeaders; //Headers to send at every client request with NetworkConnection
    public static CookieStore mCookies = null; //Headers to send at every client request with NetworkConnection
    public static CookieSpecRegistry mCookiesSpec = null; //Headers returned by the server

    /**
     * Connectivity Manager to access to the network configuration
     */
    protected ConnectivityManager mConnectivityManager;

    public DataLibService() {
        super(MAX_THREADS);
        mHeaders = new ArrayList<Header>();
    }

    public DataLibService(final int maxThreads) {
        super(maxThreads);
    }

    @Override
    public void onCreate() {
        mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        //we initialize the FileManager
        FileManager.getInstance(getApplicationContext());
        super.onCreate();
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void onHandleIntent(final Intent intent) {
        final int processorType = intent.getIntExtra(INTENT_EXTRA_PROCESSOR_TYPE, -1);

        Out.d(TAG, "onHandleIntent");

        //      String userAgent = intent.getStringExtra(INTENT_EXTRA_USER_AGENT);

        final DataLibRequest request = new DataLibRequest();
        DataLibWebConfig.applyToRequest(request, DataLibWebConfig.getInstance()); //we apply a default configuration for the request

        //we get the action data
        request.url = intent.getStringExtra(INTENT_EXTRA_URL);
        request.params = intent.getParcelableExtra(INTENT_EXTRA_PARAMS);
        request.parseType = intent.getIntExtra(INTENT_EXTRA_PARSE_TYPE, DataLibRequest.PARSE_TYPE_SAX_XML);

        //we eventually add the complex options
        Object complexOptions = intent.getSerializableExtra(INTENT_EXTRA_COMPLEX_OPTIONS);
        if (complexOptions instanceof ComplexOptions)
            request.complexOptions = (ComplexOptions) complexOptions;

        request.context = getApplicationContext();
        //we get the options to apply
        int option = intent.getIntExtra(INTENT_EXTRA_REQUEST_OPTION, DataLibRequest.OPTION_NO_OPTION);
        DataLibWebConfig.applyToRequest(request, option, true);

        //we add the intent
        request.intent = intent;

        try {

            if (processorType == COOKIES_FLUSH)
                this.flushCookies();

            else {
                //we launch the processor on a daughter class
                launchProcessor(processorType, request);
            }

        } catch (final Exception e) {
            Out.e(TAG, "Erreur", e);
            final BusinessResponse response = new BusinessResponse();
            response.status = BusinessResponse.STATUS_ERROR;
            response.statusMessage = Log.getStackTraceString(e);
            sendResult(request, response, response.status);
        }

    }

    /**
     * Function that flush the cookies stored inside the headers ArrayList
     */
    private void flushCookies() {
        for (final Header header : mHeaders) {
            if (header.getName().equalsIgnoreCase(COOKIE_HEADER_TITLE))
                mHeaders.remove(header);
        }
    }

    /**
     * Send the result of a request to the linked {@link ServiceHelper}
     * 
     * @param request the request
     * @param response the response
     * @param code the status of the request
     */
    protected void sendResult(final DataLibRequest request, final BusinessResponse response, final int code) {
        Out.d(TAG, "sendResult");

        final Intent intent = request.intent;
        final ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra(INTENT_EXTRA_RECEIVER);

        if (receiver != null) {
            final Bundle b = new Bundle();

            if (response != null && response.response != null) {

                //if the Business Object have to be transmit inside the Bundle
                if (request.isParcelableMethodEnabled())
                    b.putParcelable(ServiceHelper.RECEIVER_EXTRA_RESULT, response.response);

                //we add the request id to the response
                if (response.response instanceof ResponseBusinessObjectDAO) {
                    ResponseBusinessObjectDAO r = (ResponseBusinessObjectDAO) response.response;
                    b.putLong(ServiceHelper.RECEIVER_EXTRA_RESULT_ID, r._id);
                } else {
                    //in case of no data cache, we set an invalid ID
                    b.putLong(ServiceHelper.RECEIVER_EXTRA_RESULT_ID, BusinessObjectDAO.ID_INVALID);
                }

            } else {
                Out.e(TAG, "Unfined response");
            }

            //we copy the content of the response in the intent's bundle
            b.putInt(ServiceHelper.RECEIVER_EXTRA_REQUEST_ID, intent.getIntExtra(INTENT_EXTRA_REQUEST_ID, -1));
            b.putInt(ServiceHelper.RECEIVER_EXTRA_WEBSERVICE_TYPE,
                    intent.getIntExtra(INTENT_EXTRA_PROCESSOR_TYPE, -1));
            b.putInt(ServiceHelper.RECEIVER_EXTRA_RETURN_CODE, response.returnCode);
            b.putInt(ServiceHelper.RECEIVER_EXTRA_RESULT_CODE, response.status);
            b.putString(ServiceHelper.RECEIVER_EXTRA_RESULT_MESSAGE, "");

            receiver.send(code, b);
        }
    }

    @Override
    public void handleProcessorResponse(final DataLibResponse response) {

        final DataLibRequest request = response.request;

        //we add the cookies to the service's headers
        if (request.isConservingTheCookies()) {

            //TODO CHECK THE COOKIE CONSERVATION
            //            final Header[] headers = response.headers;
            //
            //            if (headers != null) {
            //                for (final Header header : headers) {
            //                    //if we have to keep the cookie
            //                    if (request.isConservingTheCookies() && header.getName().equalsIgnoreCase(COOKIE_HEADER_TITLE))
            //                        mHeaders.add(header);
            //                }
            //            }
        }
        sendResult(request, response, response.status);
    }

    /**
     * Function that implements the instantiation and the launching of the processor process. i-e. network requesting, parsing, ... and returning the
     * {@link DataLibResponse} through {@link handleProcessorResponse} in the {@link DataLibService} class
     * 
     * @param processorType type of response to handle
     * @param request Request passed to the Service
     */
    public abstract void launchProcessor(final int processorType, final DataLibRequest request);
}