Android Open Source - mobilib Mbl Api






From Project

Back to project page mobilib.

License

The source code is released under:

MIT License

If you think the Android project mobilib listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.datdo.mobilib.api;
//from  www . j  a va2  s  .c o  m
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.Assert;

import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import com.datdo.mobilib.util.MblUtils;

import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;

/**
 * <pre>
 * Util class for communicating with server via HTTP/HTTPS.
 * Support 2 most basic methods GET and PUT. PUT method allows file uploading.
 * Subclasses must specify cache duration for a URL by overriding {@link #getCacheDuration(String, boolean)}
 * </pre>
 */
@SuppressWarnings("deprecation")
public class MblApi {

    private static final String TAG = MblApi.class.getSimpleName();

    private static final String UTF8 = "UTF-8";
    private static final Charset CHARSET_UTF8 = Charset.forName("UTF-8");

    /**
     * <pre>
     * Send GET request asynchronously.
     * If calling thread is main thread, this method automatically creates {@link AsyncTask} and runs on that {@link AsyncTask},
     * otherwise it runs on calling thread.
     * </pre>
     * @param url starts with "http://" or "https://"
     * @param params {key,value} containing request parameters (combined with "url" to generate full URL). Value accepts String, Long, Integer, Double, Float
     * @param headerParams {key,value} containing request headers
     * @param isCacheEnabled should use cache for this request?
     * @param cacheDuration how long cache data will valid (ignore this param if isCacheEnabled is FALSE
     * @param isIgnoreSSLCertificate should ignore SSL Certificate? (in case "url" starts with "https://" only)
     * @param callback callback to receive result data (text or binary)
     * @param callbackHandler {@link Handler} links to thread on which callback 's method will be invoked
     */
    @SuppressWarnings("unchecked")
    public static void get(
            final String url,
            Map<String, ? extends Object> params,
            final Map<String, String> headerParams,
            final boolean isCacheEnabled,
            final long cacheDuration,
            final boolean isIgnoreSSLCertificate,
            final MblApiGetCallback callback,
            Handler callbackHandler) {

        Map<String, ? extends Object> paramsNoEmptyVal = getParamsIgnoreEmptyValues(params);

        final Handler fCallbackHandler;
        if (callbackHandler != null) {
            fCallbackHandler = callbackHandler;
        } else {
            fCallbackHandler = MblUtils.getMainThreadHandler();
        }

        if (!MblUtils.isEmpty(paramsNoEmptyVal)) {
            for (String key : paramsNoEmptyVal.keySet()) {
                Object val = paramsNoEmptyVal.get(key);
                if (val instanceof String) {
                    continue;
                }
                if (val instanceof Long) {
                    continue;
                }
                if (val instanceof Integer) {
                    continue;
                }
                if (val instanceof Double) {
                    continue;
                }
                if (val instanceof Float) {
                    continue;
                }

                final String message = "params " + key + " must be String, Long, Integer, Double, Float, current value is " + val.getClass().getSimpleName();
                Log.e(TAG, "GET '" + url + "': " + message);
                if (callback != null) {
                    fCallbackHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onFailure(-1, message);
                        }
                    });
                }
                return;
            }
        }

        final String fullUrl = generateGetMethodFullUrl(url, paramsNoEmptyVal);

        MblUtils.executeOnAsyncThread(new Runnable() {
            @Override
            public void run() {

                MblCache existingCache = null;
                if (isCacheEnabled) {
                    existingCache = MblCache.get(fullUrl);
                    boolean shouldReadFromCache =
                            existingCache != null &&
                            (   !MblUtils.isNetworkConnected() ||
                                    System.currentTimeMillis() - existingCache.getDate() <= cacheDuration    );
                    if (shouldReadFromCache) {
                        try {
                            final byte[] data = MblUtils.readCacheFile(existingCache.getFileName());
                            if (data != null) {
                                if (callback != null) {
                                    fCallbackHandler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            callback.onSuccess(-1, data);
                                        }
                                    });
                                }

                                return;
                            }
                        } catch (IOException e) {
                            Log.e(TAG, "Cache not exist", e);
                        }
                    }
                }

                try {

                    HttpClient httpClient = getHttpClient(fullUrl, isIgnoreSSLCertificate);
                    HttpContext httpContext = new BasicHttpContext();
                    HttpGet httpGet = new HttpGet(fullUrl);

                    httpGet.setHeaders(getHeaderArray(headerParams));

                    final HttpResponse response = httpClient.execute(httpGet, httpContext);

                    final int statusCode = response.getStatusLine().getStatusCode();
                    if (statusCode < 200 || statusCode > 299) {
                        if (callback != null) {
                            fCallbackHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    callback.onFailure(statusCode, response.getStatusLine().getReasonPhrase());
                                }
                            });
                        }

                        return;
                    }

                    final byte[] data = EntityUtils.toByteArray(response.getEntity());

                    if (isCacheEnabled) {
                        saveCache(existingCache, fullUrl, data);
                    }

                    if (callback != null) {
                        fCallbackHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                callback.onSuccess(statusCode, data);
                            }
                        });
                    }
                } catch (final Exception e) {
                    Log.e(TAG, "GET request failed due to unexpected exception", e);
                    if (callback != null) {
                        fCallbackHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                callback.onFailure(-1, "Unexpected exception: " + e.getMessage());
                            }
                        });
                    }
                }
            }
        });
    }

    /**
     * <pre>
     * Callback for {@link MblApi#get(String, Map, Map, boolean, boolean, boolean, MblApiGetCallback)}.
     * Implement {@link MblApiGetCallback#onSuccessBinary(byte[])} for binary result.
     * Implement {@link MblApiGetCallback#onSuccessText(String)} for text result (JSON, XML, etc...)
     * </pre> 
     */
    public static interface MblApiGetCallback {
        /**
         * <pre>
         * Invoked on request success.
         * </pre>
         * @param statusCode HTTP status code or -1 (in case of fetching data from cache)
         * @param data result data in byte array
         */
        public void onSuccess(int statusCode, byte[] data);
        /**
         * <pre>
         * Invoked on request failure.
         * </pre>
         * @param error HTTP status code (in case status code != 2xx) or -1 (in case of unknown error)
         * @param errorMessage error message returned from server
         */
        public abstract void onFailure(int error, String errorMessage);
    }

    /**
     * <pre>
     * Get absolute path to cache file of a URL.
     * </pre>
     * @param url starts with "http://" or "https://"
     * @param params {key,value} containing request parameters (combined with "url" to generate full URL)
     * @return
     */
    @SuppressWarnings("unchecked")
    public static String getCacheFilePath(String url, Map<String, String> params) {
        String fullUrl = generateGetMethodFullUrl(url, getParamsIgnoreEmptyValues(params));
        MblCache existingCache = MblCache.get(fullUrl);
        if (existingCache == null || existingCache.getFileName() == null) {
            return null;
        }
        String path = MblUtils.getCacheAsbPath(existingCache.getFileName());
        File file = new File(path);
        if (!file.exists() || file.length() == 0) {
            return null;
        }
        return path;
    }

    /**
     * <pre>
     * Send POST request asynchronously.
     * If calling thread is main thread, this method automatically creates {@link AsyncTask} and runs on that {@link AsyncTask},
     * otherwise it runs on calling thread.
     * </pre>
     * @param url starts with "http://" or "https://"
     * @param params {key,value} containing request parameters. Value accepts String, Long, Integer, Double, Float, InputStream or File
     * @param headerParams {key,value} containing request headers
     * @param isIgnoreSSLCertificate should ignore SSL Certificate? (in case "url" starts with "https://" only)
     * @param callback callback to receive result data
     * @param callbackHandler {@link Handler} links to thread on which callback 's method will be invoked
     */
    public static void post(
            String url,
            Map<String, ? extends Object> params,
            Map<String, String> headerParams,
            boolean isIgnoreSSLCertificate,
            MblApiPostCallback callback,
            Handler callbackHandler) {

        sendRequestWithBody(
                Method.POST,
                url,
                params,
                headerParams,
                isIgnoreSSLCertificate,
                callback,
                callbackHandler);
    }

    /**
     * <pre>
     * Callback for {@link MblApi#post(String, Map, Map, boolean, MblApiPostCallback)}
     * </pre>
     */
    public static interface MblApiPostCallback extends MblSendRequestWithBodyCallback {}

    private static enum Method {
        POST,
        PUT,
        DELETE;

        public HttpEntityEnclosingRequestBase getHttpRequest(String url) {
            if (this == POST) {
                return new HttpPost(url);
            }
            if (this == PUT) {
                return new HttpPut(url);
            }
            if (this == DELETE) {
                return new HttpDeleteWithBody(url);
            }
            return null;
        }
    }

    @SuppressWarnings("unchecked")
    private static void sendRequestWithBody(
            final Method method,
            final String url,
            Map<String, ? extends Object> params,
            final Map<String, String> headerParams,
            final boolean isIgnoreSSLCertificate,
            final MblSendRequestWithBodyCallback callback,
            Handler callbackHandler) {

        Assert.assertNotNull(method);

        final Map<String, ? extends Object> paramsNoEmptyVal = getParamsIgnoreEmptyValues(params);

        final Handler fCallbackHandler;
        if (callbackHandler != null) {
            fCallbackHandler = callbackHandler;
        } else {
            fCallbackHandler = MblUtils.getMainThreadHandler();
        }

        boolean isMultipart = false;
        if (!MblUtils.isEmpty(paramsNoEmptyVal)) {
            for (String key : paramsNoEmptyVal.keySet()) {
                Object val = paramsNoEmptyVal.get(key);
                if (val instanceof InputStream) {
                    isMultipart = true;
                    continue;
                }
                if (val instanceof File) {
                    isMultipart = true;
                    continue;
                }
                if (val instanceof String) {
                    continue;
                }
                if (val instanceof Long) {
                    continue;
                }
                if (val instanceof Integer) {
                    continue;
                }
                if (val instanceof Double) {
                    continue;
                }
                if (val instanceof Float) {
                    continue;
                }

                final String message = "params " + key + " must be String, Long, Integer, Double, Float, InputStream or File, current value is " + val.getClass().getSimpleName();
                Log.e(TAG, method.name() + " '" + url + "': " + message);
                if (callback != null) {
                    fCallbackHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onFailure(-1, message);
                        }
                    });
                }
                return;
            }
        }
        final boolean fIsMultipart = isMultipart;

        MblUtils.executeOnAsyncThread(new Runnable() {
            @Override
            public void run() {

                try {
                    HttpClient httpClient = getHttpClient(url, isIgnoreSSLCertificate);
                    HttpContext httpContext = new BasicHttpContext();
                    HttpEntityEnclosingRequestBase httpRequest = method.getHttpRequest(url);

                    if (!MblUtils.isEmpty(paramsNoEmptyVal)) {
                        if (fIsMultipart) {
                            MultipartEntity multipartContent = new MultipartEntity();
                            for (String key : paramsNoEmptyVal.keySet()) {
                                Object val = paramsNoEmptyVal.get(key);
                                if (val instanceof InputStream) {
                                    multipartContent.addPart(key, new InputStreamBody((InputStream)val, key));
                                } else if (val instanceof File) {
                                    File file = (File)val;
                                    FileInputStream fis = new FileInputStream(file);
                                    multipartContent.addPart(key, new InputStreamBody(fis, file.getName()));
                                } else if (val instanceof String){
                                    multipartContent.addPart(key, new StringBody(val.toString(), CHARSET_UTF8));
                                }
                            }
                            httpRequest.setEntity(multipartContent);
                        } else {
                            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                            for (String key : paramsNoEmptyVal.keySet()) {
                                nameValuePairs.add(new BasicNameValuePair(key, paramsNoEmptyVal.get(key).toString()));
                            }
                            httpRequest.setEntity(new UrlEncodedFormEntity(nameValuePairs, UTF8));
                        }
                    }

                    httpRequest.setHeaders(getHeaderArray(headerParams));

                    final HttpResponse response = httpClient.execute(httpRequest, httpContext);

                    final int statusCode = response.getStatusLine().getStatusCode();
                    if (statusCode < 200 || statusCode > 299) {
                        if (callback != null) {
                            fCallbackHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    callback.onFailure(
                                            statusCode,
                                            response.getStatusLine().getReasonPhrase());
                                }
                            });
                        }
                        return;
                    }

                    final String data = EntityUtils.toString(response.getEntity());

                    if (callback != null) {
                        fCallbackHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                callback.onSuccess(statusCode, data);
                            }
                        });
                    }

                } catch (final Exception e) {
                    Log.e(TAG, method.name() + " request failed due to unexpected exception", e);
                    if (callback != null) {
                        fCallbackHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                callback.onFailure(-1, "Unexpected exception: " + e.getMessage());
                            }
                        });
                    }
                }
            }
        });
    }

    private static interface MblSendRequestWithBodyCallback {
        /**
         * <pre>
         * Invoked on request success.
         * </pre>
         * @param statusCode HTTP status code
         * @param data result data in text
         */
        public void onSuccess(int statusCode, String data);
        /**
         * <pre>
         * Invoked on request failure.
         * </pre>
         * @param error HTTP status code (in case status code != 2xx) or -1 (in case of unknown error)
         * @param errorMessage error message returned from server
         */
        public void onFailure(int error, String errorMessage);

    }

    /**
     * <pre>
     * Send DELETE request asynchronously.
     * If calling thread is main thread, this method automatically creates {@link AsyncTask} and runs on that {@link AsyncTask},
     * otherwise it runs on calling thread.
     * </pre>
     * @param url starts with "http://" or "https://"
     * @param params {key,value} containing request parameters. Value accepts String, Long, Integer, Double, Float, InputStream or File
     * @param headerParams {key,value} containing request headers
     * @param isIgnoreSSLCertificate should ignore SSL Certificate? (in case "url" starts with "https://" only)
     * @param callback callback to receive result data
     * @param callbackHandler {@link Handler} links to thread on which callback 's method will be invoked
     */
    public static void delete(
            String url,
            Map<String, String> params,
            Map<String, String> headerParams,
            boolean isIgnoreSSLCertificate,
            MblApiDeleteCallback callback,
            Handler callbackHandler) {

        sendRequestWithBody(
                Method.DELETE,
                url,
                params,
                headerParams,
                isIgnoreSSLCertificate,
                callback,
                callbackHandler);
    }

    /**
     * <pre>
     * Callback for {@link MblApi#delete(String, Map, Map, boolean, MblApiDeleteCallback)
     * </pre>
     */
    public static interface MblApiDeleteCallback extends MblSendRequestWithBodyCallback {}


    /**
     * <pre>
     * Send PUT request asynchronously.
     * If calling thread is main thread, this method automatically creates {@link AsyncTask} and runs on that {@link AsyncTask},
     * otherwise it runs on calling thread.
     * </pre>
     * @param url starts with "http://" or "https://"
     * @param params {key,value} containing request parameters. Value accepts String, Long, Integer, Double, Float, InputStream or File
     * @param headerParams {key,value} containing request headers
     * @param isIgnoreSSLCertificate should ignore SSL Certificate? (in case "url" starts with "https://" only)
     * @param callback callback to receive result data
     * @param callbackHandler {@link Handler} links to thread on which callback 's method will be invoked
     */
    public static void put(
            String url,
            Map<String, ? extends Object> params,
            Map<String, String> headerParams,
            boolean isIgnoreSSLCertificate,
            MblApiPutCallback callback,
            Handler callbackHandler) {

        sendRequestWithBody(
                Method.PUT,
                url,
                params,
                headerParams,
                isIgnoreSSLCertificate,
                callback,
                callbackHandler);
    }

    /**
     * <pre>
     * Callback for {@link MblApi#put(String, Map, Map, boolean, MblApiPostCallback)
     * </pre>
     */
    public static interface MblApiPutCallback extends MblSendRequestWithBodyCallback {}

    @SuppressWarnings("unused")
    private static class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase {
        @Override
        public String getMethod() {
            return "DELETE";
        }

        public HttpDeleteWithBody(final String uri) {
            super();
            setURI(URI.create(uri));
        }

        public HttpDeleteWithBody(final URI uri) {
            super();
            setURI(uri);
        }

        public HttpDeleteWithBody() {
            super();
        }
    }

    private static HttpClient getHttpClient(String url, boolean ignoreSSLCertificate) {
        if (MblSSLCertificateUtils.isHttpsUrl(url) && ignoreSSLCertificate) {
            return MblSSLCertificateUtils.getHttpClientIgnoreSSLCertificate();
        } else {
            return new DefaultHttpClient();
        }
    }

    private static void saveCache(MblCache existingCache, String fullUrl, byte[] data) {
        try {
            MblCache cacheToSave;
            if (existingCache == null) {
                cacheToSave = new MblCache();
                cacheToSave.setKey(fullUrl);
                cacheToSave.setDate(System.currentTimeMillis());
                MblCache.insert(cacheToSave);
            } else {
                cacheToSave = existingCache;
                cacheToSave.setDate(System.currentTimeMillis());
                MblCache.update(cacheToSave);
            }
            MblUtils.saveCacheFile(data, cacheToSave.getFileName());
        } catch (Exception e) {
            Log.e(TAG, "Failed to cache url: " + fullUrl, e);
        }
    }

    private static String generateGetMethodFullUrl(String url, Map<String, ? extends Object> params) {
        if (!MblUtils.isEmpty(params)) {
            Uri.Builder builder = Uri.parse(url).buildUpon();
            for (String key : params.keySet()) {
                builder.appendQueryParameter(key, params.get(key).toString());
            }
            return builder.build().toString();
        } else {
            return url;
        }
    }

    private static Header[] getHeaderArray(Map<String, String> headerParams) {

        Header[] headers = null;

        if (!MblUtils.isEmpty(headerParams)) {
            headers = new Header[headerParams.keySet().size()];
            int i = 0;
            for (final String key : headerParams.keySet()) {
                final String val = headerParams.get(key);
                headers[i++] = new Header() {

                    @Override
                    public HeaderElement[] getElements() throws ParseException { return null; }

                    @Override
                    public String getName() {
                        return key;
                    }

                    @Override
                    public String getValue() {
                        return val;
                    }
                };
            }
        }

        return headers;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static Map getParamsIgnoreEmptyValues(Map params) {
        if (MblUtils.isEmpty(params)) {
            return params;
        }
        Map ret = new HashMap();
        for (Object key : params.keySet()) {
            Object val = params.get(key);
            if (!shouldIgnoreParamValue(val)) {
                ret.put(key, val);
            }
        }
        return ret;
    }

    private static boolean shouldIgnoreParamValue(Object val) {
        if (val == null) {
            return true;
        }
        if (val instanceof String && MblUtils.isEmpty((String)val)) {
            return true;
        }
        return false;
    }
}




Java Source Code List

com.datdo.mobilib.api.DBBase.java
com.datdo.mobilib.api.DBHelper.java
com.datdo.mobilib.api.MblApi.java
com.datdo.mobilib.api.MblCache.java
com.datdo.mobilib.api.MblException.java
com.datdo.mobilib.api.MblSSLCertificateUtils.java
com.datdo.mobilib.base.MblActivityPlugin.java
com.datdo.mobilib.base.MblBaseActionBarActivity.java
com.datdo.mobilib.base.MblBaseActivity.java
com.datdo.mobilib.base.MblBaseAdapter.java
com.datdo.mobilib.base.MblBaseApplication.java
com.datdo.mobilib.base.MblBaseFragmentActivity.java
com.datdo.mobilib.base.MblDecorView.java
com.datdo.mobilib.base.MblNetworkStatusChangedReceiver.java
com.datdo.mobilib.event.MblCommonEvents.java
com.datdo.mobilib.event.MblEventCenter.java
com.datdo.mobilib.event.MblEventListener.java
com.datdo.mobilib.event.MblStrongEventListener.java
com.datdo.mobilib.event.MblWeakArrayList.java
com.datdo.mobilib.imageinput.MblAutoResizeSquareImageView.java
com.datdo.mobilib.imageinput.MblDataInputActivity.java
com.datdo.mobilib.imageinput.MblImageFolderScanner.java
com.datdo.mobilib.imageinput.MblImageInput.java
com.datdo.mobilib.imageinput.MblImagePickingScanEngine.java
com.datdo.mobilib.imageinput.MblPickImageActivity.java
com.datdo.mobilib.imageinput.MblPickImageGridViewAdapter.java
com.datdo.mobilib.imageinput.MblTakeImageActivity.java
com.datdo.mobilib.util.MblAsyncTask.java
com.datdo.mobilib.util.MblImageLoader.java
com.datdo.mobilib.util.MblLinkMovementMethod.java
com.datdo.mobilib.util.MblUrlRecognizer.java
com.datdo.mobilib.util.MblUtils.java
com.datdo.mobilib.widget.MblHorizontalViewPager.java
com.datdo.mobilib.widget.MblListViewWithScrollableItems.java
com.datdo.mobilib.widget.MblSequenceImage.java
com.datdo.mobilib.widget.MblSideMenuEnabledLayout.java
com.datdo.mobilib.widget.MblTouchImageView.java