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.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
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
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
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
00207
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
00218
00219 return false;
00220 }
00221 } catch (NoSuchInterfaceException e) {
00222 e.printStackTrace();
00223 return false;
00224 }
00225
00226 return true;
00227 }
00228
00229
00230
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
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
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
00288 Object[] clientSideEffectiveArguments = mc.getEffectiveArguments();
00289
00290 ProActiveInterfaceType itfType = (ProActiveInterfaceType) multicastItfs.get(mc.getComponentMetadata()
00291 .getComponentInterfaceName())
00292 .getFcItfType();
00293
00294 Method matchingMethodInClientInterface;
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
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
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
00336 expectedMethodCallsNb = delegatee.size();
00337 }
00338
00339
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
00349 try {
00350
00351
00352
00353
00354
00355 Method matchingMethodInServerInterface = matchingMethods.get(mc.getComponentMetadata()
00356 .getComponentInterfaceName())
00357 .get(new SerializableMethod(
00358 mc.getReifiedMethod())).getMethod();
00359
00360
00361
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);
00372 }
00373
00374 result.put(new MethodCall(matchingMethodInServerInterface, mc.getGenericTypesMapping(),
00375 individualEffectiveArguments, mc.getExceptionContext()),
00376 generatedMethodCallIndex % delegatee.size());
00377
00378 }
00379 } catch (SecurityException e) {
00380
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
00401 e.printStackTrace();
00402 } catch (ClassNotFoundException e) {
00403
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 }