Java tutorial
/* * 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; } } }