/** * Dianping.com Inc. * Copyright (c) 2003-2013 All Rights Reserved. */ package com.dianping.pigeon.remoting.provider.service.method; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import com.dianping.pigeon.remoting.common.util.InvocationUtils; public class ServiceMethod { private Method method; private Object service; private Class<?>[] originalParameterClasses; private Class<?>[] parameterClasses; private boolean needCastParameterClasses = false; public boolean isNeedCastParameterClasses() { return needCastParameterClasses; } public void setNeedCastParameterClasses(boolean needCastParameterClasses) { this.needCastParameterClasses = needCastParameterClasses; } public Class<?>[] getParameterClasses() { return parameterClasses; } public Class<?>[] getOriginalParameterClasses() { return originalParameterClasses; } public void setParameterClasses(Class<?>[] parameterClasses) { this.parameterClasses = parameterClasses; } private int parameterLength; public ServiceMethod(Object service, Method method) { this.service = service; this.method = method; this.parameterClasses = regulateTypes(this.method.getParameterTypes()); this.originalParameterClasses = this.method.getParameterTypes(); this.parameterLength = this.parameterClasses.length; } private Class<?>[] regulateTypes(Class<?>[] types) { for (int i = 0; i < types.length; i++) { if (types[i] == byte.class) { types[i] = Byte.class; } else if (types[i] == short.class) { types[i] = Short.class; } else if (types[i] == int.class) { types[i] = Integer.class; } else if (types[i] == boolean.class) { types[i] = Boolean.class; } else if (types[i] == long.class) { types[i] = Long.class; } else if (types[i] == float.class) { types[i] = Float.class; } else if (types[i] == double.class) { types[i] = Double.class; } } return types; } public int getParameterSize() { return this.parameterLength; } public Method getMethod() { return this.method; } /** * @return the service */ public Object getService() { return service; } @Override public String toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); } public Object invoke(Object[] arguments) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { if (needCastParameterClasses && arguments != null && parameterClasses != null) { if (parameterClasses.length == arguments.length) { Object[] argumentsCast = new Object[arguments.length]; for (int i = 0; i < arguments.length; i++) { Object arg = arguments[i]; if (arg != null) { Class<?> argClass = arg.getClass(); if (argClass != parameterClasses[i]) { if (argClass.equals(Double.class) && parameterClasses[i].equals(Float.class)) { arg = ((Double) arg).floatValue(); } else if (argClass.equals(Integer.class) && parameterClasses[i].equals(Short.class)) { arg = ((Integer) arg).shortValue(); } } } argumentsCast[i] = arg; } try { return this.getMethod().invoke(this.getService(), argumentsCast); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("invalid parameter types:" + InvocationUtils.getRemoteCallFullName(this.getMethod().getName(), argumentsCast), e.getCause()); } } } try { return this.getMethod().invoke(this.getService(), arguments); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("invalid parameter types:" + InvocationUtils.getRemoteCallFullName(this.getMethod().getName(), arguments), e.getCause()); } } }