org/objectweb/proactive/core/component/collectiveitfs/GatherBindingChecker.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
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             // 1. check names
00078             if (! serverSideMethod.getName().equals(clientSideMethod.getName())) {
00079                 continue serverSideMethodsLoop;
00080             }
00081 
00082             // 2. check return types
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             // 3. check parameters types
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                         // need parameterized types for server itf parameters
00112                         // but: could be a stub, generated by javassist, which cannot add generics information
00113                         if (StubObject.class.isAssignableFrom(serverSideMethod.getDeclaringClass())) {
00114                                 // => check in implemented interfaces
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                                                         // parameter types match 
00125                                                         break;
00126                                                 }
00127                                         } catch (NoSuchMethodException e) {
00128                                                 // not in this interface
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 //                      if (! (((Class)clientSideParametersTypes[i]).isAssignableFrom((Class)pServerParameterType.getRawType()))) {
00147                                 if (clientSideParametersTypes[i] instanceof ParameterizedType && ((Class)((ParameterizedType)clientSideParametersTypes[i]).getRawType()).isAssignableFrom(List.class)) {
00148                                         // we have a list<T> in the client multicast itf, that's fine
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             // 4. check exception types
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 }

Generated on Mon Jan 22 15:16:06 2007 for ProActive by  doxygen 1.5.1