org/objectweb/proactive/core/component/controller/MulticastControllerImpl.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.controller;
00032 
00033 import java.io.Serializable;
00034 import java.lang.reflect.Method;
00035 import java.util.ArrayList;
00036 import java.util.Arrays;
00037 import java.util.HashMap;
00038 import java.util.Iterator;
00039 import java.util.List;
00040 import java.util.Map;
00041 import java.util.Vector;
00042 
00043 import org.apache.log4j.Logger;
00044 import org.objectweb.fractal.api.Component;
00045 import org.objectweb.fractal.api.NoSuchInterfaceException;
00046 import org.objectweb.fractal.api.control.IllegalBindingException;
00047 import org.objectweb.fractal.api.factory.InstantiationException;
00048 import org.objectweb.fractal.api.type.ComponentType;
00049 import org.objectweb.fractal.api.type.InterfaceType;
00050 import org.objectweb.fractal.api.type.TypeFactory;
00051 import org.objectweb.fractal.util.Fractal;
00052 import org.objectweb.proactive.core.ProActiveRuntimeException;
00053 import org.objectweb.proactive.core.component.Constants;
00054 import org.objectweb.proactive.core.component.ProActiveInterface;
00055 import org.objectweb.proactive.core.component.collectiveitfs.MulticastBindingChecker;
00056 import org.objectweb.proactive.core.component.exceptions.ParameterDispatchException;
00057 import org.objectweb.proactive.core.component.group.ProxyForComponentInterfaceGroup;
00058 import org.objectweb.proactive.core.component.type.ProActiveInterfaceType;
00059 import org.objectweb.proactive.core.component.type.ProActiveTypeFactoryImpl;
00060 import org.objectweb.proactive.core.component.type.annotations.multicast.ParamDispatch;
00061 import org.objectweb.proactive.core.group.Group;
00062 import org.objectweb.proactive.core.group.ProActiveComponentGroup;
00063 import org.objectweb.proactive.core.group.ProActiveGroup;
00064 import org.objectweb.proactive.core.mop.ClassNotReifiableException;
00065 import org.objectweb.proactive.core.mop.MethodCall;
00066 import org.objectweb.proactive.core.mop.Proxy;
00067 import org.objectweb.proactive.core.mop.StubObject;
00068 import org.objectweb.proactive.core.util.SerializableMethod;
00069 import org.objectweb.proactive.core.util.log.Loggers;
00070 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00071 
00072 
00073 public class MulticastControllerImpl
00074     extends AbstractProActiveController implements MulticastController,
00075         Serializable {
00076     private static Logger logger = ProActiveLogger.getLogger(Loggers.COMPONENTS_CONTROLLERS);
00077     private static Logger multicastLogger = ProActiveLogger.getLogger(Loggers.COMPONENTS_MULTICAST);
00078     private Map<String, ProActiveInterface> multicastItfs = new HashMap<String, ProActiveInterface>();
00079     private Map clientSideProxies = new HashMap();
00080     private Map<String, Map<SerializableMethod, SerializableMethod>> matchingMethods = new HashMap<String, Map<SerializableMethod, SerializableMethod>>();
00081 
00082     
00083 
00084     public MulticastControllerImpl(Component owner) {
00085         super(owner);
00086     }
00087 
00088     public void init() {
00089         // this method is called once the component is fully instantiated with all its interfaces created
00090         InterfaceType[] itfTypes = ((ComponentType) owner.getFcType()).getFcInterfaceTypes();
00091         for (int i = 0; i < itfTypes.length; i++) {
00092             ProActiveInterfaceType type = (ProActiveInterfaceType) itfTypes[i];
00093             if (type.isFcMulticastItf()) {
00094                 try {
00095                     addClientSideProxy(type.getFcItfName(),
00096                         (ProActiveInterface) owner.getFcInterface(
00097                             type.getFcItfName()));
00098                 } catch (NoSuchInterfaceException e) {
00099                     throw new ProActiveRuntimeException(e);
00100                 }
00101             }
00102         }
00103         List<InterfaceType> interfaceTypes = Arrays.asList(((ComponentType) owner.getFcType()).getFcInterfaceTypes());
00104         Iterator<InterfaceType> it = interfaceTypes.iterator();
00105 
00106         while (it.hasNext()) {
00107             // keep ref on interfaces of cardinality multicast
00108             addManagedInterface((ProActiveInterfaceType) it.next());
00109         }
00110     }
00111 
00119     public void ensureCompatibility(ProActiveInterfaceType clientSideItfType,
00120         ProActiveInterface serverSideItf) throws IllegalBindingException {
00121         try {
00122             ProActiveInterfaceType serverSideItfType = (ProActiveInterfaceType) serverSideItf.getFcItfType();
00123             Class clientSideItfClass;
00124             clientSideItfClass = Class.forName(clientSideItfType.getFcItfSignature());
00125             Class serverSideItfClass = Class.forName(serverSideItfType.getFcItfSignature());
00126 
00127             Method[] clientSideItfMethods = clientSideItfClass.getMethods();
00128             Method[] serverSideItfMethods = serverSideItfClass.getMethods();
00129 
00130             if (clientSideItfMethods.length != serverSideItfMethods.length) {
00131                 throw new IllegalBindingException(
00132                     "incompatible binding between client interface " +
00133                     clientSideItfType.getFcItfName() + " (" +
00134                     clientSideItfType.getFcItfSignature() +
00135                     ")  and server interface " +
00136                     serverSideItfType.getFcItfName() + " (" +
00137                     serverSideItfType.getFcItfSignature() +
00138                     ") : there is not the same number of methods (including those inherited) in both interfaces !");
00139             }
00140 
00141             Map<SerializableMethod, SerializableMethod> matchingMethodsForThisItf =
00142                 new HashMap<SerializableMethod, SerializableMethod>(clientSideItfMethods.length);
00143 
00144             for (Method method : clientSideItfMethods) {
00145                 Method serverSideMatchingMethod = searchMatchingMethod(method,
00146                         serverSideItfMethods,
00147                         clientSideItfType.isFcMulticastItf(),
00148                         serverSideItfType.isFcGathercastItf(), serverSideItf);
00149                 if (serverSideMatchingMethod == null) {
00150                     throw new IllegalBindingException(
00151                         "binding incompatibility between " +
00152                         clientSideItfType.getFcItfName() + " and " +
00153                         serverSideItfType.getFcItfName() +
00154                         " : cannot find matching method");
00155                 }
00156                 matchingMethodsForThisItf.put(new SerializableMethod(method),
00157                     new SerializableMethod(serverSideMatchingMethod));
00158             }
00159 
00160             matchingMethods.put(clientSideItfType.getFcItfName(),
00161                 matchingMethodsForThisItf);
00162         } catch (ClassNotFoundException e) {
00163             throw new IllegalBindingException(
00164                 "cannot find class corresponding to given signature " +
00165                 e.getMessage());
00166         }
00167     }
00168 
00169 
00170     /*
00171      * @see org.objectweb.proactive.core.component.controller.AbstractCollectiveInterfaceController#searchMatchingMethod(java.lang.reflect.Method, java.lang.reflect.Method[])
00172      */
00173     protected Method searchMatchingMethod(Method clientSideMethod,
00174         Method[] serverSideMethods, boolean clientItfIsMulticast,
00175         boolean serverItfIsGathercast, ProActiveInterface serverSideItf) {
00176         try {
00177             return MulticastBindingChecker.searchMatchingMethod(clientSideMethod,
00178                 serverSideMethods, serverItfIsGathercast, serverSideItf);
00179         } catch (ParameterDispatchException e) {
00180             e.printStackTrace();
00181             return null;
00182         } catch (NoSuchMethodException e) {
00183             e.printStackTrace();
00184             return null;
00185         }
00186     }
00187 
00188     protected void setControllerItfType() {
00189         try {
00190             setItfType(ProActiveTypeFactoryImpl.instance()
00191                                                .createFcItfType(Constants.MULTICAST_CONTROLLER,
00192                     MulticastController.class.getName(), TypeFactory.SERVER,
00193                     TypeFactory.MANDATORY, TypeFactory.SINGLE));
00194         } catch (InstantiationException e) {
00195             throw new ProActiveRuntimeException(
00196                 "cannot create controller type for controller " +
00197                 this.getClass().getName());
00198         }
00199     }
00200 
00201     private boolean addManagedInterface(ProActiveInterfaceType itfType) {
00202         if (!itfType.isFcMulticastItf()) {
00203             return false;
00204         }
00205         if (multicastItfs.containsKey(itfType.getFcItfName())) {
00206             //            logger.error("the interface named " + itfType.getFcItfName() +
00207             //                " is already managed by the collective interfaces controller");
00208             return false;
00209         }
00210 
00211         try {
00212             ProActiveInterface multicastItf = (ProActiveInterface) owner.getFcInterface(itfType.getFcItfName());
00213 
00214             if (itfType.isFcMulticastItf()) {
00215                 multicastItfs.put(itfType.getFcItfName(), multicastItf);
00216             } else {
00217                 //                logger.error("the interface named " + itfType.getFcItfName() +
00218                 //                    " cannot be managed by this collective interfaces controller");
00219                 return false;
00220             }
00221         } catch (NoSuchInterfaceException e) {
00222             e.printStackTrace();
00223             return false;
00224         }
00225 
00226         return true;
00227     }
00228 
00229     /*
00230      * @see org.objectweb.proactive.core.component.controller.MulticastController#bindFc(java.lang.String, org.objectweb.proactive.core.component.ProActiveInterface)
00231      */
00232     public void bindFcMulticast(String clientItfName,
00233         ProActiveInterface serverItf) {
00234         init();
00235         if (logger.isDebugEnabled()) {
00236             try {
00237                 if (!ProActiveGroup.isGroup(serverItf.getFcItfOwner())) {
00238                     logger.debug("multicast binding : " + clientItfName +
00239                         " to : " +
00240                         Fractal.getNameController(serverItf.getFcItfOwner())
00241                                .getFcName() + "." + serverItf.getFcItfName());
00242                 }
00243             } catch (NoSuchInterfaceException e) {
00244                 e.printStackTrace();
00245             }
00246         }
00247         if (multicastItfs.containsKey(clientItfName)) {
00248             bindFc(clientItfName, serverItf);
00249         }
00250     }
00251 
00252     /*
00253      * @see org.objectweb.proactive.core.component.controller.MulticastController#unbindFc(java.lang.String, org.objectweb.proactive.core.component.ProActiveInterface)
00254      */
00255     public void unbindFcMulticast(String clientItfName,
00256         ProActiveInterface serverItf) {
00257         if (multicastItfs.containsKey(clientItfName)) {
00258             if (ProActiveGroup.getGroup(multicastItfs.get(clientItfName))
00259                                   .remove(serverItf)) {
00260                 logger.debug(
00261                     "removed connected interface from multicast interface : " +
00262                     clientItfName);
00263             } else {
00264                 logger.error(
00265                     "cannot remove connected interface from multicast interface : " +
00266                     clientItfName);
00267             }
00268         }
00269     }
00270 
00271     /*
00272      * @see org.objectweb.proactive.core.component.controller.MulticastController#lookupFc(java.lang.String)
00273      */
00274     public ProxyForComponentInterfaceGroup lookupFcMulticast(
00275         String clientItfName) {
00276         if (multicastItfs.containsKey(clientItfName)) {
00277             return (ProxyForComponentInterfaceGroup) ((ProActiveInterface) multicastItfs.get(clientItfName)
00278                                                                                         .getFcItfImpl()).getProxy();
00279         } else {
00280             return null;
00281         }
00282     }
00283 
00284     public Map<MethodCall, Integer> generateMethodCallsForMulticastDelegatee(
00285         MethodCall mc, ProxyForComponentInterfaceGroup delegatee)
00286         throws ParameterDispatchException {
00287         // read from annotations
00288         Object[] clientSideEffectiveArguments = mc.getEffectiveArguments();
00289 
00290         ProActiveInterfaceType itfType = (ProActiveInterfaceType) multicastItfs.get(mc.getComponentMetadata()
00291                                                                                       .getComponentInterfaceName())
00292                                                                                .getFcItfType();
00293 
00294         Method matchingMethodInClientInterface; // client itf as well as parent interfaces
00295 
00296         try {
00297             matchingMethodInClientInterface = Class.forName(itfType.getFcItfSignature())
00298                                                    .getMethod(mc.getReifiedMethod()
00299                                                                 .getName(),
00300                     mc.getReifiedMethod().getParameterTypes());
00301         } catch (Exception e) {
00302             e.printStackTrace();
00303             throw new ParameterDispatchException(e.fillInStackTrace());
00304         }
00305 
00306         Class[] clientSideParamTypes = matchingMethodInClientInterface.getParameterTypes();
00307         ParamDispatch[] clientSideParamDispatchModes = MulticastBindingChecker.getDispatchModes(matchingMethodInClientInterface);
00308 
00309         List<List<Object>> dispatchedParameters = new ArrayList<List<Object>>();
00310 
00311         int expectedMethodCallsNb = 0;
00312 
00313         // compute dispatch sizes for annotated parameters
00314         Vector<Integer> dispatchSizes = new Vector<Integer>();
00315 
00316         for (int i = 0; i < clientSideParamTypes.length; i++) {
00317             dispatchSizes.addElement(clientSideParamDispatchModes[i].expectedDispatchSize(
00318                     clientSideEffectiveArguments[i], delegatee.size()));
00319         }
00320 
00321         if (dispatchSizes.size() > 0) {
00322             // ok, found some annotated elements
00323             expectedMethodCallsNb = dispatchSizes.get(0);
00324 
00325             for (int i = 1; i < dispatchSizes.size(); i++) {
00326                 if (dispatchSizes.get(i).intValue() != expectedMethodCallsNb) {
00327                     throw new ParameterDispatchException(
00328                         "cannot generate invocation for multicast interface " +
00329                         itfType.getFcItfName() +
00330                         "because the specified distribution of parameters is incorrect in method " +
00331                         matchingMethodInClientInterface.getName());
00332                 }
00333             }
00334         } else {
00335             // broadcast to every member of the group
00336             expectedMethodCallsNb = delegatee.size();
00337         }
00338 
00339         // get distributed parameters
00340         for (int i = 0; i < clientSideParamTypes.length; i++) {
00341             List<Object> dispatchedParameter = clientSideParamDispatchModes[i].dispatch(clientSideEffectiveArguments[i],
00342                     delegatee.size());
00343             dispatchedParameters.add(dispatchedParameter);
00344         }
00345 
00346         Map<MethodCall, Integer> result = new HashMap<MethodCall, Integer>(expectedMethodCallsNb);
00347 
00348         // need to find matching method in server interface
00349         try {
00350 //            if (matchingMethods.get(mc.getComponentMetadata()
00351 //                                          .getComponentInterfaceName()) == null) {
00352 //                System.out.println("########## \n" +
00353 //                    matchingMethods.toString());
00354 //            }
00355             Method matchingMethodInServerInterface = matchingMethods.get(mc.getComponentMetadata()
00356                                                                            .getComponentInterfaceName())
00357                                                                     .get(new SerializableMethod(
00358                         mc.getReifiedMethod())).getMethod();
00359 
00360             // now we have all dispatched parameters
00361             // proceed to generation of method calls
00362             for (int generatedMethodCallIndex = 0;
00363                     generatedMethodCallIndex < expectedMethodCallsNb;
00364                     generatedMethodCallIndex++) {
00365                 Object[] individualEffectiveArguments = new Object[matchingMethodInServerInterface.getParameterTypes().length];
00366 
00367                 for (int parameterIndex = 0;
00368                         parameterIndex < individualEffectiveArguments.length;
00369                         parameterIndex++) {
00370                     individualEffectiveArguments[parameterIndex] = dispatchedParameters.get(parameterIndex)
00371                                                                                        .get(generatedMethodCallIndex); // initialize
00372                 }
00373 
00374                 result.put(new MethodCall(matchingMethodInServerInterface, mc.getGenericTypesMapping(), 
00375                         individualEffectiveArguments, mc.getExceptionContext()),
00376                     generatedMethodCallIndex % delegatee.size());
00377                 // default is to do some round robin when nbGeneratedMethodCalls > nbReceivers
00378             }
00379         } catch (SecurityException e) {
00380             // TODO Auto-generated catch block
00381             e.printStackTrace();
00382         }
00383 
00384         return result;
00385     }
00386 
00387     private void bindFc(String clientItfName, ProActiveInterface serverItf) {
00388         try {
00389             ProxyForComponentInterfaceGroup clientSideProxy = (ProxyForComponentInterfaceGroup) clientSideProxies.get(clientItfName);
00390 
00391             if (clientSideProxy.getDelegatee() == null) {
00392                 ProActiveInterface groupItf = ProActiveComponentGroup.newComponentInterfaceGroup((ProActiveInterfaceType) serverItf.getFcItfType(),
00393                         owner);
00394                 ProxyForComponentInterfaceGroup proxy = (ProxyForComponentInterfaceGroup) ((StubObject) groupItf).getProxy();
00395                 clientSideProxy.setDelegatee(proxy);
00396             }
00397 
00398             ((Group) clientSideProxy.getDelegatee()).add(serverItf);
00399         } catch (ClassNotReifiableException e) {
00400             // TODO Auto-generated catch block
00401             e.printStackTrace();
00402         } catch (ClassNotFoundException e) {
00403             // TODO Auto-generated catch block
00404             e.printStackTrace();
00405         }
00406     }
00407 
00408     private boolean hasClientSideProxy(String itfName) {
00409         return clientSideProxies.containsKey(itfName);
00410     }
00411 
00412     private void addClientSideProxy(String itfName, ProActiveInterface itf) {
00413         Proxy proxy = ((ProActiveInterface) itf.getFcItfImpl()).getProxy();
00414 
00415         if (!(proxy instanceof Group)) {
00416             throw new ProActiveRuntimeException(
00417                 "client side proxies for multicast interfaces must be Group instances");
00418         }
00419 
00420         clientSideProxies.put(itfName, proxy);
00421     }
00422 }

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