/** * Dianping.com Inc. * Copyright (c) 2003-2013 All Rights Reserved. */ package com.dianping.pigeon.remoting.invoker.service; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import com.dianping.pigeon.log.Logger; import com.dianping.pigeon.log.LoggerLoader; import com.dianping.pigeon.remoting.common.domain.InvocationResponse; import com.dianping.pigeon.remoting.common.exception.BadResponseException; import com.dianping.pigeon.remoting.common.process.ServiceInvocationHandler; import com.dianping.pigeon.remoting.common.util.Constants; import com.dianping.pigeon.remoting.invoker.config.InvokerConfig; import com.dianping.pigeon.remoting.invoker.domain.DefaultInvokerContext; import com.dianping.pigeon.remoting.invoker.util.InvokerUtils; public class ServiceInvocationProxy implements InvocationHandler { private static final Logger logger = LoggerLoader.getLogger(ServiceInvocationProxy.class); private InvokerConfig<?> invokerConfig; private ServiceInvocationHandler handler; public ServiceInvocationProxy(InvokerConfig<?> invokerConfig, ServiceInvocationHandler handler) { this.invokerConfig = invokerConfig; this.handler = handler; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); Class<?>[] parameterTypes = method.getParameterTypes(); if (method.getDeclaringClass() == Object.class) { return method.invoke(handler, args); } if ("toString".equals(methodName) && parameterTypes.length == 0) { return handler.toString(); } if ("hashCode".equals(methodName) && parameterTypes.length == 0) { return handler.hashCode(); } if ("equals".equals(methodName) && parameterTypes.length == 1) { return handler.equals(args[0]); } return extractResult(handler.handle(new DefaultInvokerContext(invokerConfig, methodName, parameterTypes, args)), method.getReturnType()); } public Object extractResult(InvocationResponse response, Class<?> returnType) throws Throwable { Object responseReturn = response.getReturn(); if (responseReturn != null) { int messageType = response.getMessageType(); if (messageType == Constants.MESSAGE_TYPE_SERVICE) { return responseReturn; } else if (messageType == Constants.MESSAGE_TYPE_EXCEPTION) { throw InvokerUtils.toRpcException(response); } else if (messageType == Constants.MESSAGE_TYPE_SERVICE_EXCEPTION) { throw InvokerUtils.toApplicationException(response); } throw new BadResponseException(response.toString()); } return getReturn(returnType); } private Object getReturn(Class<?> returnType) { if (returnType == byte.class) { return (byte) 0; } else if (returnType == short.class) { return (short) 0; } else if (returnType == int.class) { return 0; } else if (returnType == boolean.class) { return false; } else if (returnType == long.class) { return 0l; } else if (returnType == float.class) { return 0.0f; } else if (returnType == double.class) { return 0.0d; } else { return null; } } }