me.xiaopan.android.gohttp.requestobject.RequestParser.java Source code

Java tutorial

Introduction

Here is the source code for me.xiaopan.android.gohttp.requestobject.RequestParser.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.requestobject;

import android.content.Context;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import me.xiaopan.android.gohttp.MethodType;
import me.xiaopan.android.gohttp.RequestParams;

/**
 * ??Request
 */
public class RequestParser {
    private static final String DEFAULT_VALUE_TRUE = "true";
    private static final String DEFAULT_VALUE_FALSE = "false";

    /**
     * ?????????GETDELETE
     * @param context 
     * @param requestClass class
     * @return ?nullrequestClassnullUrlHost
     */
    public static String parseBaseUrl(Context context, Class<? extends Request> requestClass) {
        StringBuilder stringBuilder = new StringBuilder();

        /* ?Url */
        String url = parseURLAnnotation(context, requestClass);
        if (url != null && !"".equals(url)) {
            stringBuilder.append(url);
        } else {
            /* ?Host */
            if (stringBuilder.length() == 0) {
                String host = parseHostAnnotation(context, requestClass);
                if (host != null && !"".equals(host)) {
                    stringBuilder.append(host);
                }
            }

            /* ??Path */
            if (stringBuilder.length() > 0) {
                String path = parsePathAnnotation(context, requestClass);
                if (path != null && !"".equals(path)) {
                    stringBuilder.append("/");
                    stringBuilder.append(path);
                }
            }
        }

        if (stringBuilder.length() > 0) {
            return stringBuilder.toString();
        } else {
            return null;
        }
    }

    /**
     * ??Get??
     * @param context 
     * @param requestClass class
     * @param extraRequestParams ???GETDELETE???
     * @return ?nullrequestClassnullUrlHost
     */
    public static String parseCompleteUrl(Context context, Class<? extends Request> requestClass,
            RequestParams extraRequestParams) {
        StringBuilder stringBuilder = new StringBuilder();

        /* ?Url */
        String url = parseURLAnnotation(context, requestClass);
        if (url != null && !"".equals(url)) {
            stringBuilder.append(url);
        } else {
            /* ?Host */
            if (stringBuilder.length() == 0) {
                String host = parseHostAnnotation(context, requestClass);
                if (host != null && !"".equals(host)) {
                    stringBuilder.append(host);
                }
            }

            /* ??Path */
            if (stringBuilder.length() > 0) {
                String path = parsePathAnnotation(context, requestClass);
                if (path != null && !"".equals(path)) {
                    stringBuilder.append("/");
                    stringBuilder.append(path);
                }
            }
        }

        if (stringBuilder.length() > 0) {
            Method method = requestClass.getAnnotation(Method.class);
            if (method == null || method.value() == MethodType.GET || method.value() == MethodType.DELETE) {
                RequestParams newParams = parseRequestParams(context, requestClass, extraRequestParams);
                String paramString = newParams.getParamString();
                if (paramString != null && !"".equals(paramString)) {
                    stringBuilder.append(stringBuilder.indexOf("?") == -1 ? "?" : "&");
                    stringBuilder.append(paramString);
                }
            }
            return stringBuilder.toString();
        } else {
            return null;
        }
    }

    /**
     * ????????
     * @param context 
     * @param requestClass class
     * @return ?nullrequestClassnullUrlHost
     */
    public static String parseCompleteUrl(Context context, Class<? extends Request> requestClass) {
        return parseCompleteUrl(context, requestClass, null);
    }

    /**
     * ??Get??
     * @param context 
     * @param request 
     * @param extraRequestParams ???GETDELETE???
     * @return ?nullrequestClassnullUrlHost
     */
    public static String parseCompleteUrl(Context context, Request request, RequestParams extraRequestParams) {
        StringBuilder stringBuilder = new StringBuilder();

        /* ?Url */
        String url = parseURLAnnotation(context, request.getClass());
        if (url != null && !"".equals(url)) {
            stringBuilder.append(url);
        } else {
            /* ?Host */
            String host = parseHostAnnotation(context, request.getClass());
            if (host != null && !"".equals(host)) {
                stringBuilder.append(host);
            }

            /* ??Path */
            if (stringBuilder.length() > 0) {
                String path = parsePathAnnotation(context, request.getClass());
                if (path != null && !"".equals(path)) {
                    stringBuilder.append("/");
                    stringBuilder.append(path);
                }
            }
        }

        if (stringBuilder.length() > 0) {
            Method method = request.getClass().getAnnotation(Method.class);
            if (method == null || method.value() == MethodType.GET || method.value() == MethodType.DELETE) {
                RequestParams newParams = parseRequestParams(context, request, extraRequestParams);
                String paramString = newParams.getParamString();
                if (paramString != null && !"".equals(paramString)) {
                    stringBuilder.append(stringBuilder.indexOf("?") == -1 ? "?" : "&");
                    stringBuilder.append(paramString);
                }
            }
            return stringBuilder.toString();
        } else {
            return null;
        }
    }

    /**
     * ??Get??
     * @param context 
     * @param request 
     * @return ?nullrequestClassnullUrlHost
     */
    public static String parseCompleteUrl(Context context, Request request) {
        return parseCompleteUrl(context, request, null);
    }

    /**
     * ??
     * @param context 
     * @param requestClass class??class??????
     * @param requestParams ??null????????
     * @return ?
     */
    @SuppressWarnings("unchecked")
    public static RequestParams parseRequestParams(Context context, Class<? extends Request> requestClass,
            RequestParams requestParams) {
        if (requestParams == null) {
            requestParams = new RequestParams();
        }

        String requestParamName;
        String requestParamValue;
        Object requestParamValueObject = null;
        for (Field field : getFields(requestClass, true, true, true)) {
            // ???????
            if (!field.isAnnotationPresent(Param.class) || !Modifier.isStatic(field.getModifiers())) {
                continue;
            }

            // ????
            requestParamName = parseParamAnnotation(context, field);
            if (requestParamName == null) {
                requestParamName = field.getName();
            }

            // ?ValueValue?
            if (field.isAnnotationPresent(Value.class)) {
                String value = parseValueAnnotation(context, field);
                if (value != null) {
                    requestParams.put(requestParamName, value);
                    continue;
                }
            }

            try {
                field.setAccessible(true);
                requestParamValueObject = field.get(null);
            } catch (Exception e) {
                e.printStackTrace();
            }

            // ?null?
            if (requestParamValueObject == null) {
                continue;
            }

            // ?Map???
            if (Map.class.isAssignableFrom(field.getType())) {
                for (java.util.Map.Entry<Object, Object> entry : ((Map<Object, Object>) requestParamValueObject)
                        .entrySet()) {
                    if (entry.getKey() != null && entry.getValue() != null) {
                        String key = entry.getKey().toString();
                        String value = entry.getValue().toString();
                        if (key != null && !"".equals(key) && value != null && !"".equals(value)) {
                            requestParams.put(key, value);
                        }
                    }
                }
                continue;
            }

            // ?File?
            if (File.class.isAssignableFrom(field.getType())) {
                try {
                    requestParams.put(requestParamName, (File) requestParamValueObject);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                continue;
            }

            // ?ArrayListArrayList?
            if (ArrayList.class.isAssignableFrom(field.getType())) {
                requestParams.put(requestParamName, (ArrayList<String>) requestParamValueObject);
                continue;
            }

            // ?boolean
            if (Boolean.class.isAssignableFrom(field.getType())) {
                if ((Boolean) requestParamValueObject) {
                    requestParamValue = parseTrueAnnotation(context, field);
                    if (requestParamValue == null) {
                        requestParamValue = DEFAULT_VALUE_TRUE;
                    }
                } else {
                    requestParamValue = parseFalseAnnotation(context, field);
                    if (requestParamValue == null) {
                        requestParamValue = DEFAULT_VALUE_FALSE;
                    }
                }
                requestParams.put(requestParamName, requestParamValue);
                continue;
            }

            // ?
            if (Enum.class.isAssignableFrom(field.getType())) {
                Enum<?> enumObject = (Enum<?>) requestParamValueObject;
                requestParamValue = parseValueAnnotationFromEnum(context, enumObject);
                if (requestParamValue == null) {
                    requestParamValue = enumObject.name();
                }
                requestParams.put(requestParamName, requestParamValue);
                continue;
            }

            // ???
            requestParamValue = requestParamValueObject.toString();
            if (requestParamValue != null && !"".equals(requestParamValue)) {
                requestParams.put(requestParamName, requestParamValue);
            }
        }

        return requestParams;
    }

    /**
     * ??
     * @param context 
     * @param requestClass class??class??????
     * @return ?
     */
    public static RequestParams parseRequestParams(Context context, Class<? extends Request> requestClass) {
        return parseRequestParams(context, requestClass, null);
    }

    /**
     * ??
     * @param context 
     * @param request 
     * @param requestParams ??null????????
     * @return ?
     */
    @SuppressWarnings("unchecked")
    public static RequestParams parseRequestParams(Context context, Request request, RequestParams requestParams) {
        if (requestParams == null) {
            requestParams = new RequestParams();
        }

        String requestParamName;
        String requestParamValue;
        Object requestParamValueObject = null;
        for (Field field : getFields(request.getClass(), true, true, true)) {
            // ????
            if (!field.isAnnotationPresent(Param.class)) {
                continue;
            }

            // ????
            requestParamName = parseParamAnnotation(context, field);
            if (requestParamName == null) {
                requestParamName = field.getName();
            }

            // ?ValueValue?
            if (field.isAnnotationPresent(Value.class)) {
                String value = parseValueAnnotation(context, field);
                if (value != null) {
                    requestParams.put(requestParamName, value);
                    continue;
                }
            }

            try {
                field.setAccessible(true);
                requestParamValueObject = field.get(request);
            } catch (Exception e) {
                e.printStackTrace();
            }

            // ?null?
            if (requestParamValueObject == null) {
                continue;
            }

            // ?Map???
            if (Map.class.isAssignableFrom(field.getType())) {
                for (java.util.Map.Entry<Object, Object> entry : ((Map<Object, Object>) requestParamValueObject)
                        .entrySet()) {
                    if (entry.getKey() != null && entry.getValue() != null) {
                        String key = entry.getKey().toString();
                        String value = entry.getValue().toString();
                        if (key != null && !"".equals(key) && value != null && !"".equals(value)) {
                            requestParams.put(key, value);
                        }
                    }
                }
                continue;
            }

            // ?File?
            if (File.class.isAssignableFrom(field.getType())) {
                try {
                    requestParams.put(requestParamName, (File) requestParamValueObject);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                continue;
            }

            // ?ArrayListArrayList?
            if (ArrayList.class.isAssignableFrom(field.getType())) {
                requestParams.put(requestParamName, (ArrayList<String>) requestParamValueObject);
                continue;
            }

            // ?boolean
            if (Boolean.class.isAssignableFrom(field.getType())) {
                if ((Boolean) requestParamValueObject) {
                    requestParamValue = parseTrueAnnotation(context, field);
                    if (requestParamValue == null) {
                        requestParamValue = DEFAULT_VALUE_TRUE;
                    }
                } else {
                    requestParamValue = parseFalseAnnotation(context, field);
                    if (requestParamValue == null) {
                        requestParamValue = DEFAULT_VALUE_FALSE;
                    }
                }
                requestParams.put(requestParamName, requestParamValue);
                continue;
            }

            // ?
            if (Enum.class.isAssignableFrom(field.getType())) {
                Enum<?> enumObject = (Enum<?>) requestParamValueObject;
                requestParamValue = parseValueAnnotationFromEnum(context, enumObject);
                if (requestParamValue == null) {
                    requestParamValue = enumObject.name();
                }
                requestParams.put(requestParamName, requestParamValue);
                continue;
            }

            // ???
            requestParamValue = requestParamValueObject.toString();
            if (requestParamValue != null && !"".equals(requestParamValue)) {
                requestParams.put(requestParamName, requestParamValue);
            }
        }

        return requestParams;
    }

    /**
     * ??
     * @param context 
     * @param request 
     * @return ?
     */
    public static RequestParams parseRequestParams(Context context, Request request) {
        return parseRequestParams(context, request, null);
    }

    /**
     * ?
     * @param request 
     */
    @SuppressWarnings("unchecked")
    public static org.apache.http.Header[] parseRequestHeaders(Request request) {
        List<org.apache.http.Header> finalHeaders = null;
        for (Field field : getFields(request.getClass(), true, true, true)) {
            field.setAccessible(true);
            if (field.getAnnotation(Header.class) != null) { //???
                try {
                    Object value = field.get(request);
                    if (value != null) {
                        if (org.apache.http.Header.class.isAssignableFrom(field.getType())) { //?
                            if (finalHeaders == null) {
                                finalHeaders = new LinkedList<org.apache.http.Header>();
                            }
                            finalHeaders.add((org.apache.http.Header) value);
                        } else if (isArrayByType(field, org.apache.http.Header.class)) { //Header
                            org.apache.http.Header[] headers = (org.apache.http.Header[]) value;
                            for (org.apache.http.Header header : headers) {
                                if (header != null) {
                                    if (finalHeaders == null) {
                                        finalHeaders = new LinkedList<org.apache.http.Header>();
                                    }
                                    finalHeaders.add(header);
                                }
                            }
                        } else if (isCollectionByType(field, Collection.class, org.apache.http.Header.class)) { //Header?
                            if (finalHeaders == null) {
                                finalHeaders = new LinkedList<org.apache.http.Header>();
                            }
                            finalHeaders.addAll((Collection<org.apache.http.Header>) value);
                        }
                    }
                } catch (IllegalAccessException e1) {
                    e1.printStackTrace();
                } catch (IllegalArgumentException e1) {
                    e1.printStackTrace();
                }
            }
        }

        if (finalHeaders != null && finalHeaders.size() > 0) {
            org.apache.http.Header[] heades = new org.apache.http.Header[finalHeaders.size()];
            finalHeaders.toArray(heades);
            return heades;
        } else {
            return null;
        }
    }

    /**
     * ??ID??
     * @param context 
     * @param requestClass class
     */
    public static List<String> parseCacheIgnoreParams(Context context, Class<? extends Request> requestClass) {
        List<String> finalHeaders = null;
        for (Field field : getFields(requestClass, true, true, true)) {
            field.setAccessible(true);
            if (field.getAnnotation(CacheIgnore.class) != null) { //?ID
                if (finalHeaders == null) {
                    finalHeaders = new LinkedList<String>();
                }
                String requestParamName = parseParamAnnotation(context, field);
                if (requestParamName == null) {
                    requestParamName = field.getName();
                }
                finalHeaders.add(requestParamName);
            }
        }
        return finalHeaders;
    }

    /**
     * ?False
     * @param context 
     * @param field ?
     */
    public static String parseFalseAnnotation(Context context, Field field) {
        False annotation = field.getAnnotation(False.class);
        if (annotation == null) {
            return null;
        }
        String annotationValue = annotation.value();
        if (annotationValue != null && !"".equals(annotationValue)) {
            return annotationValue;
        } else if (context != null && annotation.resId() > 0) {
            return context.getString(annotation.resId());
        } else {
            return null;
        }
    }

    /**
     * ??
     * @param context 
     * @param requestClass 
     */
    public static String parseHostAnnotation(Context context, Class<? extends Request> requestClass) {
        Host annotation = requestClass.getAnnotation(Host.class);
        if (annotation == null) {
            return null;
        }
        String annotationValue = annotation.value();
        if (annotationValue != null && !"".equals(annotationValue)) {
            return annotationValue;
        } else if (context != null && annotation.resId() > 0) {
            return context.getString(annotation.resId());
        } else {
            return null;
        }
    }

    /**
     * ???
     * @param context 
     * @param requestClass 
     */
    public static String parseNameAnnotation(Context context, Class<? extends Request> requestClass) {
        Name annotation = requestClass.getAnnotation(Name.class);
        if (annotation == null) {
            return null;
        }
        String annotationValue = annotation.value();
        if (annotationValue != null && !"".equals(annotationValue)) {
            return annotationValue;
        } else if (context != null && annotation.resId() > 0) {
            return context.getString(annotation.resId());
        } else {
            return null;
        }
    }

    /**
     * ????
     * @param context 
     * @param field 
     */
    public static String parseParamAnnotation(Context context, Field field) {
        Param annotation = field.getAnnotation(Param.class);
        if (annotation == null) {
            return null;
        }
        String annotationValue = annotation.value();
        if (annotationValue != null && !"".equals(annotationValue)) {
            return annotationValue;
        } else if (context != null && annotation.resId() > 0) {
            return context.getString(annotation.resId());
        } else {
            return null;
        }
    }

    /**
     * ?
     * @param context 
     * @param requestClass 
     */
    public static String parsePathAnnotation(Context context, Class<? extends Request> requestClass) {
        Path annotation = requestClass.getAnnotation(Path.class);
        if (annotation == null) {
            return null;
        }
        String annotationValue = annotation.value();
        if (annotationValue != null && !"".equals(annotationValue)) {
            return annotationValue;
        } else if (context != null && annotation.resId() > 0) {
            return context.getString(annotation.resId());
        } else {
            return null;
        }
    }

    /**
     * ????
     * @param context 
     * @param requestClass class
     */
    public static me.xiaopan.android.gohttp.CacheConfig parseResponseCacheAnnotation(Context context,
            Class<? extends Request> requestClass) {
        me.xiaopan.android.gohttp.requestobject.CacheConfig annotation = requestClass
                .getAnnotation(me.xiaopan.android.gohttp.requestobject.CacheConfig.class);
        if (annotation == null) {
            return null;
        }

        me.xiaopan.android.gohttp.CacheConfig cacheConfig = new me.xiaopan.android.gohttp.CacheConfig();
        cacheConfig.setRefreshCache(annotation.isRefreshCache());
        cacheConfig.setPeriodOfValidity(annotation.periodOfValidity());
        cacheConfig.setRefreshCallback(annotation.isRefreshCallback());
        String cacheDirectory = annotation.cacheDirectory();
        if (cacheDirectory != null && !"".equals(cacheDirectory)) {
            cacheConfig.setCacheDirectory(cacheDirectory);
        } else if (context != null && annotation.cacheDirectoryResId() > 0) {
            cacheConfig.setCacheDirectory(context.getString(annotation.cacheDirectoryResId()));
        }
        return cacheConfig;
    }

    /**
     * ?True
     * @param context 
     * @param field ?
     */
    public static String parseTrueAnnotation(Context context, Field field) {
        True annotation = field.getAnnotation(True.class);
        if (annotation == null) {
            return null;
        }
        String annotationValue = annotation.value();
        if (annotationValue != null && !"".equals(annotationValue)) {
            return annotationValue;
        } else if (context != null && annotation.resId() > 0) {
            return context.getString(annotation.resId());
        } else {
            return null;
        }
    }

    /**
     * ?URL
     * @param context 
     * @param requestClass 
     */
    public static String parseURLAnnotation(Context context, Class<? extends Request> requestClass) {
        URL annotation = requestClass.getAnnotation(URL.class);
        if (annotation == null) {
            return null;
        }
        String annotationValue = annotation.value();
        if (annotationValue != null && !"".equals(annotationValue)) {
            return annotationValue;
        } else if (context != null && annotation.resId() > 0) {
            return context.getString(annotation.resId());
        } else {
            return null;
        }
    }

    /**
     * ??
     * @param context 
     * @param field 
     */
    public static String parseValueAnnotation(Context context, Field field) {
        Value annotation = field.getAnnotation(Value.class);
        if (annotation == null) {
            return null;
        }
        String annotationValue = annotation.value();
        if (annotationValue != null && !"".equals(annotationValue)) {
            return annotationValue;
        } else if (context != null && annotation.resId() > 0) {
            return context.getString(annotation.resId());
        } else {
            return null;
        }
    }

    /**
     * ?Value
     * @param context 
     * @param enumObject 
     */
    public static String parseValueAnnotationFromEnum(Context context, Enum<?> enumObject) {
        Value annotation = null;
        try {
            annotation = enumObject.getClass().getField(enumObject.name()).getAnnotation(Value.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (annotation == null) {
            return null;
        }
        String annotationValue = annotation.value();
        if (annotationValue != null && !"".equals(annotationValue)) {
            return annotationValue;
        } else if (context != null && annotation.resId() > 0) {
            return context.getString(annotation.resId());
        } else {
            return null;
        }
    }

    /**
     * ?
     * @param sourceClass 
     * @param isAddCurrentClass ??
     * @return 
     */
    private static List<Class<?>> getSuperClasses(Class<?> sourceClass, boolean isAddCurrentClass) {
        List<Class<?>> classList = new ArrayList<Class<?>>();
        Class<?> currentClass;
        if (isAddCurrentClass) {
            currentClass = sourceClass;
        } else {
            currentClass = sourceClass.getSuperclass();
        }
        while (currentClass != null) {
            classList.add(currentClass);
            currentClass = currentClass.getSuperclass();
        }
        return classList;
    }

    /**
     * ?
     * @param sourceClass 
     * @param isGetDeclaredField ???Declared
     * @param isFromSuperClassGet ???
     * @param isDESCGet ???????????
     * @return 
     */
    private static List<Field> getFields(Class<?> sourceClass, boolean isGetDeclaredField,
            boolean isFromSuperClassGet, boolean isDESCGet) {
        List<Field> fieldList = new ArrayList<Field>();
        //??
        if (isFromSuperClassGet) {
            //??
            List<Class<?>> classList = getSuperClasses(sourceClass, true);

            //???
            if (isDESCGet) {
                for (int w = classList.size() - 1; w > -1; w--) {
                    for (Field field : isGetDeclaredField ? classList.get(w).getDeclaredFields()
                            : classList.get(w).getFields()) {
                        fieldList.add(field);
                    }
                }
            } else {
                for (int w = 0; w < classList.size(); w++) {
                    for (Field field : isGetDeclaredField ? classList.get(w).getDeclaredFields()
                            : classList.get(w).getFields()) {
                        fieldList.add(field);
                    }
                }
            }
        } else {
            for (Field field : isGetDeclaredField ? sourceClass.getDeclaredFields() : sourceClass.getFields()) {
                fieldList.add(field);
            }
        }
        return fieldList;
    }

    /**
     * ?type
     */
    private static boolean isArrayByType(Field field, Class<?> type) {
        Class<?> fieldType = field.getType();
        return fieldType.isArray() && type.isAssignableFrom(fieldType.getComponentType());
    }

    /**
     * ?typecollectionType?collectionType=List.classtype=Date.class??DateList
     */
    @SuppressWarnings("rawtypes")
    private static boolean isCollectionByType(Field field, Class<? extends Collection> collectionType,
            Class<?> type) {
        Class<?> fieldType = field.getType();
        if (collectionType.isAssignableFrom(fieldType)) {
            Class<?> first = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
            return type.isAssignableFrom(first);
        } else {
            return false;
        }
    }
}