package com.litesuits.http.request.query; import com.litesuits.http.data.Charsets; import com.litesuits.http.data.Consts; import com.litesuits.http.data.NameValuePair; import com.litesuits.http.request.param.*; import com.litesuits.http.request.param.HttpCustomParam.CustomValueBuilder; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; /** * abstract class for build parameter of request url. * * @author MaTianyu * 2014-1-4下午5:06:37 */ public abstract class ModelQueryBuilder { protected String charSet = Charsets.UTF_8; public LinkedList<NameValuePair> buildPrimaryPairSafely(HttpParamModel model) { try { return buildPrimaryPair(model); } catch (Exception e) { e.printStackTrace(); } return null; } public LinkedList<NameValuePair> buildPrimaryPair(HttpParamModel model) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, UnsupportedEncodingException { LinkedHashMap<String, String> map = buildPrimaryMap(model); LinkedList<NameValuePair> list = new LinkedList<NameValuePair>(); for (Map.Entry<String, String> entry : map.entrySet()) { list.add(new NameValuePair(entry.getKey(), entry.getValue())); } return list; } public LinkedHashMap<String, String> buildPrimaryMap(HttpParamModel model) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, UnsupportedEncodingException { if (model == null) { return null; } // find all field. ArrayList<Field> fieldList = getAllDeclaredFields(model.getClass()); LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(fieldList.size()); // put all field and its value into map for (int i = 0, size = fieldList.size(); i < size; i++) { Field f = fieldList.get(i); f.setAccessible(true); HttpParam keyAnno = f.getAnnotation(HttpParam.class); String key = keyAnno != null ? keyAnno.value() : f.getName(); Object value = f.get(model); if (value != null) { // value is primitive if (isPrimitive(value)) { map.put(key, value.toString()); } else if (value instanceof HttpCustomParam) { Method methods[] = HttpCustomParam.class.getDeclaredMethods(); for (Method m : methods) { // invoke the method which has specified Annotation if (m.getAnnotation(CustomValueBuilder.class) != null) { m.setAccessible(true); Object v = m.invoke(value); if (v != null) { map.put(key, v.toString()); } break; } } } else { CharSequence cs = buildSencondaryValue(value); if (cs != null) { map.put(key, cs.toString()); } } } } return map; } protected abstract CharSequence buildSencondaryValue(Object model); /********************* utils method **************************/ protected StringBuilder buildUriKey(StringBuilder sb, String key) throws UnsupportedEncodingException { if (key != null) sb.append(encode(key)).append(Consts.EQUALS); return sb; } public String decode(String content) throws UnsupportedEncodingException { return URLDecoder.decode(content, charSet); } public String encode(String content) throws UnsupportedEncodingException { return URLEncoder.encode(content, charSet); } // protected boolean isInvalidField(Field f) { // return (f.getAnnotation(NonHttpParam.class) != null) || f.isSynthetic(); // } protected static boolean isInvalidField(Field f) { return (Modifier.isStatic(f.getModifiers()) && Modifier.isFinal(f.getModifiers())) || (f.getAnnotation(NonHttpParam.class) != null) || f.isSynthetic(); } protected static boolean isPrimitive(Object value) { return value instanceof CharSequence || value instanceof Number || value instanceof Boolean || value instanceof Character; } protected static ArrayList<Field> getAllDeclaredFields(Class<?> claxx) { // find all field. ArrayList<Field> fieldList = new ArrayList<Field>(); while (claxx != null && claxx != HttpRichParamModel.class && claxx != Object.class) { Field[] fs = claxx.getDeclaredFields(); for (int i = 0; i < fs.length; i++) { Field f = fs[i]; if (!isInvalidField(f)) { fieldList.add(f); } } claxx = claxx.getSuperclass(); } return fieldList; } }