package com.jqmobile.core.server.servlet2;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.jqmobile.core.http.HttpRequestErrorException;
import com.jqmobile.core.http.HttpUtils;
import com.jqmobile.core.http2.HttpException;
import com.jqmobile.core.http2.HttpSerializableObject;
import com.jqmobile.core.server.service.ServiceFactory;
import com.jqmobile.core.server.session.Session;
import com.jqmobile.core.service.Login;
import com.jqmobile.core.service.Service;
import com.jqmobile.core.utils.json.$Gson$Types;
import com.jqmobile.core.utils.json.JSONArray;
import com.jqmobile.core.utils.json.JSONConvertor2;
import com.jqmobile.core.utils.json.JSONException;
import com.jqmobile.core.utils.json.JSONObject;
import com.jqmobile.core.utils.json.JsonArrayResult;
public class HttpServiceUtil {
private static HttpServiceUtil util = new HttpServiceUtil();
protected HttpServiceUtil() {
}
protected static void setHttpServiceUtil(HttpServiceUtil util){
HttpServiceUtil.util = util;
}
public static HttpSerializableObject invoke(HttpSerializableObject obj, HttpServletRequest request) {
return util.invoke_(obj, request);
}
public HttpSerializableObject invoke_(HttpSerializableObject obj, HttpServletRequest request) {
HttpSerializableObject ret = new HttpSerializableObject();
ret.setIntf(obj.getIntf());
ret.setMethod(obj.getMethod());
try {
Class<?> intfClass = getClassForName(obj);
Service ma = intfClass.getAnnotation(Service.class);
if (null == ma) {
throw new HttpRequestErrorException("ManagerAnnotation没有找到"
+ obj.getIntf());
}
JSONArray params;
if(null != obj.getData()){
params = new JSONArray(obj.getData());
}else{
params = new JSONArray();
}
JsonArrayResult paramResult = JSONConvertor2
.unSerializableArray_Result(params);
Object service = ServiceFactory.instance(intfClass);
Method method = getMethod(service.getClass(), obj.getMethod(),
paramResult.getParamClass());// implClass.getMethod(methodName,
// parameterTypes);//
// ReturnObject形式返回
if (null == obj.getSession()) {
Method m1 = getMethod(intfClass, obj.getMethod(),
paramResult.getParamClass());
Login l = m1.getAnnotation(Login.class);
if (null == l) {
// return null;
throw new HttpException(HttpException.SESSION_NULL);
}else{
Session.activate(request);
ret.setSession(Session.getSession().getId());
}
}
Object retObj = method.invoke(service, paramResult.getObjs());
JSONObject retObjJson = autoReturnJson(retObj,
List.class);// , LoadOnGetList.class, List.class);
// returnJSON.put(HttpUtils.REQUEST_ERRORED, false);
// returnJSON.put(HttpUtils.RESPONSE_DATA, responseData);
JSONArray array = new JSONArray();
array.put(retObjJson);
ret.setData(array.toString());
} catch (Throwable e) {
JSONArray retException = new JSONArray();
JSONObject eJson = new JSONObject();
try {
returnException(eJson, e);
} catch (JSONException e1) {
e1.printStackTrace();
}
ret.setException(retException.toString());
e.printStackTrace();
}
return ret;
}
protected Class<?> getClassForName(HttpSerializableObject obj)
throws ClassNotFoundException {
return Class.forName(obj.getIntf(), true, Thread
.currentThread().getContextClassLoader());
}
public JSONObject autoReturnJson(Object ret, Class<?>... havJsonClass) {
if (null == ret) {
return JSONConvertor2.serializable(ret);
}
if (ret.getClass().isArray()) {
return JSONConvertor2.serializable(ret, ret.getClass(), true);
}
for (Class<?> c : havJsonClass) {
if (c.isAssignableFrom(ret.getClass())) {
if (ret instanceof List) {
List<?> list = ((List<?>) ret);
if (!list.isEmpty()) {
return returnJson(list.get(0).getClass(),
ret.getClass(), ret);
}
} else {
return returnJson(null, ret.getClass(), ret);
}
}
}
return JSONConvertor2.serializable(ret);
}
public void main(String[] arg1s) {
List<Integer> ret = new ArrayList<Integer>();
Class<?> clazz = ret.getClass();
while (clazz != Object.class) {
Type t = clazz.getGenericSuperclass();
if (t instanceof ParameterizedType) {
Type[] args = ((ParameterizedType) t)
.getActualTypeArguments();
if (args[0] instanceof Class) {
Class<?> c = (Class<?>) args[0];
System.out.println(c);
break;
}
}
clazz = clazz.getSuperclass();
}
}
private JSONObject returnJson(Class<?> parameterizedType,
Class<?> rawClass, Object ret) {
JSONObject responseData;
// if(paramResult.getObjs().length>0 && paramResult.getObjs()[0]
// instanceof Class<?>){
// Class<?> c = (Class<?>) paramResult.getObjs()[0];
if (null != parameterizedType) {
ParameterizedType type = $Gson$Types
.newParameterizedTypeWithOwner(null, rawClass,
parameterizedType);
responseData = JSONConvertor2.serializable(ret, type, true);
} else {
responseData = JSONConvertor2.serializable(ret);
}
return responseData;
}
public Method getMethod(Class<?> implClass, String methodName,
Class<?>... params) throws SecurityException,
NoSuchMethodException {
if (null == params || 0 == params.length) {
return implClass.getMethod(methodName);
}
// 20130813
Method cacheMethod = null;
try {
cacheMethod = implClass.getDeclaredMethod(methodName, params);
} catch (Exception e) {
}
if (null != cacheMethod) {
return cacheMethod;
}
//
Method[] ms = implClass.getMethods();
L1: for (Method m : ms) {
if (!m.getName().equals(methodName)) {
continue;
}
Class<?>[] types = m.getParameterTypes();
if (null == types || 0 == types.length
|| types.length != params.length) {
continue;
}
for (int i = 0; i < types.length; i++) {
Class<?> p = params[i];
Class<?> t = types[i];
if (!equals(p, t)) {
continue L1;
}
}
return m;
}
// 20130813
L1: for (Method m : ms) {
if (!m.getName().equals(methodName)) {
continue;
}
Class<?>[] types = m.getParameterTypes();
if (null == types || 0 == types.length
|| types.length != params.length) {
continue;
}
for (int i = 0; i < types.length; i++) {
Class<?> p = params[i];
Class<?> t = types[i];
if (!equals1(p, t)) {
continue L1;
}
}
return m;
}
//
return null;
}
private boolean equals1(Class<?> p, Class<?> t) {
if (p.equals(t)) {
return true;
} else if (p.equals(Integer.class)) {
return t.equals(int.class);
} else if (p.equals(Long.class)) {
return t.equals(long.class);
} else if (p.equals(Float.class)) {
return t.equals(float.class);
} else if (p.equals(Double.class)) {
return t.equals(double.class);
} else if (p.equals(Byte.class)) {
return t.equals(byte.class);
} else if (p.equals(Short.class)) {
return t.equals(short.class);
} else if (p.equals(Character.class)) {
return t.equals(char.class);
} else if (p.equals(Boolean.class)) {
return t.equals(boolean.class);
} else {
return t.isAssignableFrom(p);
}
// return false;
}
private boolean equals(Class<?> p, Class<?> t) {
if (null == p) {
return true;
} else if (p.equals(t)) {
return true;
} else if (p.equals(Integer.class)) {
return t.equals(int.class);
} else if (p.equals(Long.class)) {
return t.equals(long.class);
} else if (p.equals(Float.class)) {
return t.equals(float.class);
} else if (p.equals(Double.class)) {
return t.equals(double.class);
} else if (p.equals(Byte.class)) {
return t.equals(byte.class);
} else if (p.equals(Short.class)) {
return t.equals(short.class);
} else if (p.equals(Character.class)) {
return t.equals(char.class);
} else if (p.equals(Boolean.class)) {
return t.equals(boolean.class);
}
return false;
}
public void returnException(JSONObject returnJSON, Throwable e)
throws JSONException {
if (e instanceof InvocationTargetException
&& null != ((InvocationTargetException) e).getTargetException()) {
e = ((InvocationTargetException) e).getTargetException();
}
returnJSON.put(HttpUtils.REQUEST_ERRORED, true);
returnJSON.put(HttpUtils.RESPONSE_ERROR_MSG, e.getMessage());
if (e instanceof Throwable) {
returnJSON.put(HttpUtils.RESPONSE_ERROR_EXCEPTION_CLASS,
e.getClass());
} else {
returnJSON.put(HttpUtils.RESPONSE_ERROR_EXCEPTION_CLASS,
Throwable.class);
}
}
}