00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.core.component.collectiveitfs;
00032
00033 import java.io.Serializable;
00034 import java.lang.reflect.Method;
00035 import java.lang.reflect.ParameterizedType;
00036 import java.lang.reflect.Type;
00037 import java.util.List;
00038
00039 import org.objectweb.proactive.core.component.exceptions.ParameterDispatchException;
00040 import org.objectweb.proactive.core.mop.ClassNotReifiableException;
00041 import org.objectweb.proactive.core.mop.MOP;
00042 import org.objectweb.proactive.core.mop.StubObject;
00043 import org.objectweb.proactive.core.mop.Utils;
00044
00050 public class GatherBindingChecker implements Serializable {
00051
00063 public static Method searchMatchingMethod(Method clientSideMethod, Method[] serverSideMethods, boolean clientItfIsMulticast) throws ParameterDispatchException, NoSuchMethodException {
00064
00065 Method result = null;
00066 Type clientSideReturnType = clientSideMethod.getGenericReturnType();
00067 Type[] clientSideParametersTypes = clientSideMethod.getGenericParameterTypes();
00068 Class[] clientSideExceptionTypes = clientSideMethod.getExceptionTypes();
00069
00070 if (!Utils.checkMethod(clientSideMethod)) {
00071 throw new NoSuchMethodException("gather interfaces only accept client interfaces with reifiable methods, which is not the case for " + clientSideMethod.toGenericString());
00072 }
00073
00074
00075 serverSideMethodsLoop:
00076 for (Method serverSideMethod : serverSideMethods) {
00077
00078 if (! serverSideMethod.getName().equals(clientSideMethod.getName())) {
00079 continue serverSideMethodsLoop;
00080 }
00081
00082
00083 if (!(clientSideReturnType == Void.TYPE)) {
00084 Type returnType = serverSideMethod.getGenericReturnType();
00085 if (!(returnType instanceof ParameterizedType)) {
00086 throw new NoSuchMethodException("gather interfaces only accept client interfaces with parameterized return types, which is not the case for " + clientSideMethod.toGenericString());
00087 }
00088 Class serverSideReturnTypeArgument = (Class) ((ParameterizedType) returnType).getActualTypeArguments()[0];
00089 try {
00090 MOP.checkClassIsReifiable(((Class)clientSideReturnType));
00091 } catch (ClassNotReifiableException e) {
00092 throw new NoSuchMethodException("gather interfaces only accept client interfaces with reifiable return types, which is not the case for " + clientSideMethod.toGenericString());
00093 }
00094
00095 if (!(serverSideReturnTypeArgument.isAssignableFrom((Class)clientSideReturnType))) {
00096 continue serverSideMethodsLoop;
00097 }
00098 } else {
00099 if (!(serverSideMethod.getReturnType() == Void.TYPE)) {
00100 continue serverSideMethodsLoop;
00101 }
00102 }
00103
00104
00105 Type[] serverSideParametersTypes = serverSideMethod.getGenericParameterTypes();
00106
00107 serverSideParametersTypesLoop:
00108 for (int i=0; i<serverSideParametersTypes.length; i++) {
00109 ParameterizedType pServerParameterType = null;
00110 if (!(serverSideParametersTypes[i] instanceof ParameterizedType)) {
00111
00112
00113 if (StubObject.class.isAssignableFrom(serverSideMethod.getDeclaringClass())) {
00114
00115 Class[] implementedInterfaces = serverSideMethod.getDeclaringClass().getInterfaces();
00116 for (int j = 0; j < implementedInterfaces.length; j++) {
00117 try {
00118 Method serverSideMethodFromImplementedItf = implementedInterfaces[j].getMethod(serverSideMethod.getName(), serverSideMethod.getParameterTypes());
00119 Type[] serverSideMethodFromImplementedItfParametersTypes = serverSideMethodFromImplementedItf.getGenericParameterTypes();
00120 if (!(serverSideMethodFromImplementedItfParametersTypes[i] instanceof ParameterizedType)) {
00121 continue serverSideMethodsLoop;
00122 } else {
00123 pServerParameterType = (ParameterizedType)serverSideMethodFromImplementedItfParametersTypes[i];
00124
00125 break;
00126 }
00127 } catch (NoSuchMethodException e) {
00128
00129 continue;
00130 }
00131 }
00132 } else {
00133 continue serverSideMethodsLoop;
00134 }
00135 } else {
00136 pServerParameterType = (ParameterizedType)serverSideParametersTypes[i];
00137 }
00138 if (!List.class.isAssignableFrom((Class)pServerParameterType.getRawType())) {
00139 continue serverSideMethodsLoop;
00140 }
00141 if (pServerParameterType.getActualTypeArguments().length != 1) {
00142 continue serverSideMethodsLoop;
00143 }
00144
00145 if (clientItfIsMulticast) {
00146
00147 if (clientSideParametersTypes[i] instanceof ParameterizedType && ((Class)((ParameterizedType)clientSideParametersTypes[i]).getRawType()).isAssignableFrom(List.class)) {
00148
00149 if (!((Class)(((ParameterizedType)clientSideParametersTypes[i]).getActualTypeArguments()[0])).isAssignableFrom((Class)pServerParameterType.getActualTypeArguments()[0])) {
00150 continue serverSideMethodsLoop;
00151 }
00152 } else {
00153 continue serverSideMethodsLoop;
00154 }
00155
00156 } else {
00157 if (!(((Class)clientSideParametersTypes[i]).isAssignableFrom((Class)pServerParameterType.getActualTypeArguments()[0]))) {
00158 continue serverSideMethodsLoop;
00159 }
00160 }
00161
00162 }
00163
00164
00165 Class[] serverSideExceptionTypes = serverSideMethod.getExceptionTypes();
00166 for (Class clientExceptionType : clientSideExceptionTypes) {
00167 boolean match = false;
00168 for (Class serverExceptionType : serverSideExceptionTypes) {
00169 if (clientExceptionType.isAssignableFrom(serverExceptionType)) {
00170 match = true;
00171 break;
00172 }
00173 }
00174 if (!match) {
00175 throw new NoSuchMethodException("found a matching method in server interface for " + clientSideMethod.toGenericString() + " but the types of thrown exceptions do not match");
00176 }
00177 }
00178
00179 if (result != null) {
00180 throw new NoSuchMethodException("cannot find matching method for " + clientSideMethod.toGenericString() + " because there are several matches in the server interface ");
00181 } else {
00182 result = serverSideMethod;
00183 }
00184
00185 }
00186
00187 if (result == null) {
00188 throw new NoSuchMethodException("cannot find matching method for " + clientSideMethod.toGenericString());
00189 }
00190
00191 return result;
00192 }
00193 }