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.Proxy;
00035 import java.util.ArrayList;
00036 import java.util.Iterator;
00037 import java.util.List;
00038 
00039 import org.objectweb.fractal.api.Component;
00040 import org.objectweb.fractal.api.Interface;
00041 import org.objectweb.fractal.api.NoSuchInterfaceException;
00042 import org.objectweb.fractal.api.control.BindingController;
00043 import org.objectweb.fractal.api.control.IllegalBindingException;
00044 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
00045 import org.objectweb.fractal.api.control.LifeCycleController;
00046 import org.objectweb.fractal.api.factory.InstantiationException;
00047 import org.objectweb.fractal.api.type.ComponentType;
00048 import org.objectweb.fractal.api.type.InterfaceType;
00049 import org.objectweb.fractal.api.type.TypeFactory;
00050 import org.objectweb.fractal.util.Fractal;
00051 import org.objectweb.proactive.ProActive;
00052 import org.objectweb.proactive.core.ProActiveRuntimeException;
00053 import org.objectweb.proactive.core.component.Binding;
00054 import org.objectweb.proactive.core.component.Bindings;
00055 import org.objectweb.proactive.core.component.Constants;
00056 import org.objectweb.proactive.core.component.Fractive;
00057 import org.objectweb.proactive.core.component.ItfStubObject;
00058 import org.objectweb.proactive.core.component.ProActiveInterface;
00059 import org.objectweb.proactive.core.component.Utils;
00060 import org.objectweb.proactive.core.component.exceptions.InterfaceGenerationFailedException;
00061 import org.objectweb.proactive.core.component.gen.GatherItfAdapterProxy;
00062 import org.objectweb.proactive.core.component.gen.OutputInterceptorClassGenerator;
00063 import org.objectweb.proactive.core.component.identity.ProActiveComponent;
00064 import org.objectweb.proactive.core.component.identity.ProActiveComponentImpl;
00065 import org.objectweb.proactive.core.component.representative.ItfID;
00066 import org.objectweb.proactive.core.component.type.ProActiveInterfaceType;
00067 import org.objectweb.proactive.core.component.type.ProActiveInterfaceTypeImpl;
00068 import org.objectweb.proactive.core.component.type.ProActiveTypeFactoryImpl;
00069 import org.objectweb.proactive.core.group.ProActiveGroup;
00070 
00071 
00079 public class ProActiveBindingControllerImpl extends AbstractProActiveController
00080     implements ProActiveBindingController, Serializable {
00081     private Bindings bindings; 
00082 
00083     
00084 
00085     
00086     public ProActiveBindingControllerImpl(Component owner) {
00087         super(owner);
00088         bindings = new Bindings();
00089     }
00090 
00091     protected void setControllerItfType() {
00092         try {
00093             setItfType(ProActiveTypeFactoryImpl.instance()
00094                                                .createFcItfType(Constants.BINDING_CONTROLLER,
00095                     ProActiveBindingController.class.getName(),
00096                     TypeFactory.SERVER, TypeFactory.MANDATORY,
00097                     TypeFactory.SINGLE));
00098         } catch (InstantiationException e) {
00099             throw new ProActiveRuntimeException(
00100                 "cannot create controller type for controller " +
00101                 this.getClass().getName());
00102         }
00103     }
00104 
00105     public void addBinding(Binding binding) {
00106         bindings.add(binding);
00107     }
00108 
00109     protected void checkBindability(String clientItfName, Interface serverItf)
00110         throws NoSuchInterfaceException, IllegalBindingException, 
00111             IllegalLifeCycleException {
00112         if (!(serverItf instanceof ProActiveInterface)) {
00113             throw new IllegalBindingException(
00114                 "Can only bind interfaces of type ProActiveInterface");
00115         }
00116 
00117         ProActiveInterfaceType clientItfType = (ProActiveInterfaceType) Utils.getItfType(clientItfName,
00118                 owner);
00119 
00120         
00121         
00122         
00123         
00124         
00125         
00126         
00127         
00128         
00129         
00130         
00131         if (!(Fractal.getLifeCycleController(getFcItfOwner())).getFcState()
00132                   .equals(LifeCycleController.STOPPED)) {
00133             throw new IllegalLifeCycleException(
00134                 "component has to be stopped to perform binding operations");
00135         }
00136 
00137         
00138         
00139         if (Utils.isMulticastItf(clientItfName, getFcItfOwner())) {
00140             Fractive.getMulticastController(owner)
00141                     .ensureCompatibility(clientItfType,
00142                 (ProActiveInterface) serverItf);
00143 
00144             
00145             if (isPrimitive()) {
00146                 BindingController userBindingController = (BindingController) ((ProActiveComponent) owner).getReferenceOnBaseObject();
00147 
00148                 if ((userBindingController.lookupFc(clientItfName) == null) ||
00149                         !(ProActiveGroup.isGroup(userBindingController.lookupFc(
00150                                 clientItfName)))) {
00151                     userBindingController.bindFc(clientItfName,
00152                         owner.getFcInterface(clientItfName));
00153                 }
00154             }
00155         }
00156 
00157         if (Utils.isGathercastItf(serverItf)) {
00158             Fractive.getGathercastController(owner)
00159                     .ensureCompatibility(clientItfType,
00160                 (ProActiveInterface) serverItf);
00161         }
00162         
00163         else if (Utils.isSingletonItf(clientItfName, getFcItfOwner())) {
00164             InterfaceType sType = (InterfaceType) serverItf.getFcItfType();
00165 
00166             
00167             InterfaceType cType = ((ComponentType) owner.getFcType()).getFcInterfaceType(clientItfName);
00168 
00169             try {
00170                 Class s = Class.forName(sType.getFcItfSignature());
00171                 Class c = Class.forName(cType.getFcItfSignature());
00172                 if (!c.isAssignableFrom(s)) {
00173                     throw new IllegalBindingException(
00174                         "The server interface type " + s.getName() +
00175                         " is not a subtype of the client interface type " +
00176                         c.getName());
00177                 }
00178             } catch (ClassNotFoundException e) {
00179                 throw new IllegalBindingException(
00180                     "Cannot find type of interface : " + e.getMessage());
00181             }
00182         }
00183 
00184         
00185         
00186         if (!isPrimitive()) {
00187             
00188             
00189             if (existsBinding(clientItfName)) {
00190                 if (!((ProActiveInterfaceTypeImpl) ((Interface) getFcItfOwner()
00191                                                                         .getFcInterface(clientItfName)).getFcItfType()).isFcCollectionItf()) {
00192                     
00193                     
00194                     controllerLogger.warn(Fractal.getNameController(
00195                             getFcItfOwner()).getFcName() + "." + clientItfName +
00196                         " is already bound");
00197 
00198                     throw new IllegalBindingException(clientItfName +
00199                         " is already bound");
00200                 } else {
00201                     
00202                     if (((InterfaceType) serverItf.getFcItfType()).isFcClientItf()) {
00203                         
00204                         throw new IllegalBindingException(serverItf.getFcItfName() +
00205                             " is not a server interface");
00206                     }
00207                 }
00208             }
00209         }
00210 
00211         
00212         
00213         
00214         
00215     }
00216 
00217     protected void checkUnbindability(String clientItfName)
00218         throws NoSuchInterfaceException, IllegalBindingException, 
00219             IllegalLifeCycleException {
00220         checkLifeCycleIsStopped();
00221         checkClientInterfaceName(clientItfName);
00222 
00223         if (!existsBinding(clientItfName)) {
00224             throw new IllegalBindingException(clientItfName +
00225                 " is not yet bound");
00226         }
00227 
00228         if (Utils.getItfType(clientItfName, owner).isFcCollectionItf()) {
00229             throw new IllegalBindingException(
00230                 "In this implementation, for coherency reasons, it is not possible to unbind members of a collection interface");
00231         }
00232     }
00233 
00241     public Object removeBinding(String clientItfName) {
00242         return bindings.remove(clientItfName);
00243     }
00244 
00252     public Object getBinding(String clientItfName) {
00253         return bindings.get(clientItfName);
00254     }
00255 
00261     public Object lookupFc(String clientItfName)
00262         throws NoSuchInterfaceException {
00263         if (isPrimitive()) {
00264             return ((BindingController) ((ProActiveComponent) getFcItfOwner()).getReferenceOnBaseObject()).lookupFc(clientItfName);
00265         } else {
00266             if (!existsBinding(clientItfName)) {
00267                 return null;
00268             } else {
00269                 return ((Binding) getBinding(clientItfName)).getServerInterface();
00270             }
00271         }
00272     }
00273 
00278     public void bindFc(String clientItfName, Object serverItf)
00279         throws NoSuchInterfaceException, IllegalBindingException, 
00280             IllegalLifeCycleException {
00281         
00282         
00283         serverItf = ProActive.getFutureValue(serverItf);
00284         
00285         ProActiveInterface sItf = (ProActiveInterface) serverItf;
00286         if (controllerLogger.isDebugEnabled()) {
00287             String serverComponentName;
00288 
00289             if (ProActiveGroup.isGroup(serverItf)) {
00290                 serverComponentName = "a group of components ";
00291             } else {
00292                 serverComponentName = Fractal.getNameController((sItf).getFcItfOwner())
00293                                              .getFcName();
00294             }
00295 
00296             controllerLogger.debug("binding " +
00297                 Fractal.getNameController(getFcItfOwner()).getFcName() + "." +
00298                 clientItfName + " to " + serverComponentName + "." +
00299                 (sItf).getFcItfName());
00300         }
00301 
00302         checkBindability(clientItfName, (Interface) serverItf);
00303 
00304         ((ItfStubObject) serverItf).setSenderItfID(new ItfID(clientItfName,
00305                 ((ProActiveComponent) getFcItfOwner()).getID()));
00306 
00307         
00308         
00309         
00310         
00311         List outputInterceptors = ((ProActiveComponentImpl) getFcItfOwner()).getOutputInterceptors();
00312 
00313         if (!outputInterceptors.isEmpty()) {
00314             try {
00315                 
00316                 sItf = OutputInterceptorClassGenerator.instance()
00317                                                       .generateInterface(sItf,
00318                         outputInterceptors);
00319             } catch (InterfaceGenerationFailedException e) {
00320                 controllerLogger.error(
00321                     "could not generate output interceptor for client interface " +
00322                     clientItfName + " : " + e.getMessage());
00323 
00324                 e.printStackTrace();
00325                 throw new IllegalBindingException(
00326                     "could not generate output interceptor for client interface " +
00327                     clientItfName + " : " + e.getMessage());
00328             }
00329         }
00330 
00331         
00332         if (Utils.isMulticastItf(clientItfName, owner)) {
00333             if (Utils.isGathercastItf(sItf)) {
00334                 
00335                 
00336                 
00337                 Fractive.getMulticastController(owner)
00338                         .bindFcMulticast(clientItfName, sItf);
00339                 
00340                 
00341                 Fractive.getGathercastController((ProActiveComponent) (sItf).getFcItfOwner())
00342                         .addedBindingOnServerItf(sItf.getFcItfName(),
00343                     ((ProActiveComponent) owner).getRepresentativeOnThis(),
00344                     clientItfName);
00345             } else {
00346                 Fractive.getMulticastController(owner)
00347                         .bindFcMulticast(clientItfName, sItf);
00348             }
00349             return;
00350         }
00351 
00352         if (isPrimitive()) {
00353             
00354             ProActiveInterfaceType sItfType = ((ProActiveInterfaceType) sItf.getFcItfType());
00355 
00356             if (Utils.isGathercastItf(sItf)) {
00357                 primitiveBindFc(clientItfName,
00358                     getGathercastAdaptor(clientItfName, serverItf, sItf));
00359                 
00360                 
00361                 Fractive.getGathercastController((ProActiveComponent) (sItf).getFcItfOwner())
00362                         .addedBindingOnServerItf(sItf.getFcItfName(),
00363                     ((ProActiveComponent) owner).getRepresentativeOnThis(),
00364                     clientItfName);
00365             } else {
00366                 primitiveBindFc(clientItfName, sItf);
00367             }
00368             return;
00369         }
00370 
00371         
00372         InterfaceType client_itf_type;
00373 
00374         client_itf_type = Utils.getItfType(clientItfName, owner);
00375 
00376         if (isComposite()) {
00377             if (Utils.isGathercastItf(sItf)) {
00378                 compositeBindFc(clientItfName, client_itf_type,
00379                     getGathercastAdaptor(clientItfName, serverItf, sItf));
00380                 
00381                 
00382                 Fractive.getGathercastController((ProActiveComponent) (sItf).getFcItfOwner())
00383                         .addedBindingOnServerItf(sItf.getFcItfName(),
00384                     ((ProActiveComponent) owner).getRepresentativeOnThis(),
00385                     clientItfName);
00386             } else {
00387                 compositeBindFc(clientItfName, client_itf_type, sItf);
00388             }
00389         }
00390     }
00391 
00392     private ProActiveInterface getGathercastAdaptor(String clientItfName,
00393         Object serverItf, ProActiveInterface sItf)
00394         throws NoSuchInterfaceException {
00395         
00396         Class clientItfClass = null;
00397         try {
00398             InterfaceType[] cItfTypes = ((ComponentType) owner.getFcType()).getFcInterfaceTypes();
00399             for (int i = 0; i < cItfTypes.length; i++) {
00400                 if (clientItfName.equals(cItfTypes[i].getFcItfName()) ||
00401                         (cItfTypes[i].isFcCollectionItf() &&
00402                         clientItfName.startsWith(cItfTypes[i].getFcItfName()))) {
00403                     clientItfClass = Class.forName(cItfTypes[i].getFcItfSignature());
00404                 }
00405             }
00406             if (clientItfClass == null) {
00407                 throw new ProActiveRuntimeException(
00408                     "could not find type of client interface " + clientItfName);
00409             }
00410         } catch (ClassNotFoundException e) {
00411             throw new ProActiveRuntimeException(
00412                 "cannot find client interface class for client interface : " +
00413                 clientItfName);
00414         }
00415         ProActiveInterface itfProxy = (ProActiveInterface) Proxy.newProxyInstance(Thread.currentThread()
00416                                                                                         .getContextClassLoader(),
00417                 new Class[] { ProActiveInterface.class, clientItfClass },
00418                 new GatherItfAdapterProxy(serverItf));
00419         return itfProxy;
00420     }
00421 
00422     private void primitiveBindFc(String clientItfName,
00423         ProActiveInterface serverItf)
00424         throws NoSuchInterfaceException, IllegalBindingException, 
00425             IllegalLifeCycleException {
00426         
00427         BindingController user_binding_controller = (BindingController) ((ProActiveComponent) getFcItfOwner()).getReferenceOnBaseObject();
00428 
00429         
00430         
00431         serverItf = (ProActiveInterface) ProActive.getFutureValue(serverItf);
00432         user_binding_controller.bindFc(clientItfName, serverItf);
00433         
00434     }
00435 
00436     
00437 
00438 
00439 
00440     private void compositeBindFc(String clientItfName,
00441         InterfaceType clientItfType, Interface serverItf)
00442         throws NoSuchInterfaceException, IllegalBindingException, 
00443             IllegalLifeCycleException {
00444         ProActiveInterface clientItf = null;
00445         clientItf = (ProActiveInterface) getFcItfOwner()
00446                                              .getFcInterface(clientItfName);
00447         
00448         
00449         
00450         
00451         
00452         if (clientItfType.getFcItfName().equals(clientItfName)) {
00453             
00454             
00455             
00456             
00457             
00458             
00459             
00460             clientItf.setFcItfImpl(serverItf);
00461             
00462         } else {
00463             if (Utils.getItfType(clientItfName, owner).isFcCollectionItf()) {
00464                 clientItf.setFcItfImpl(serverItf);
00465             } else {
00466                 
00467                 
00468                 
00469                 
00470                 
00471                 throw new NoSuchInterfaceException("Cannot bind interface " +
00472                     clientItfName +
00473                     " because it does not correspond to the specified type");
00474             }
00475         }
00476         
00477         addBinding(new Binding(clientItf, clientItfName, serverItf));
00478     }
00479 
00480     
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488     public void unbindFc(String clientItfName)
00489         throws NoSuchInterfaceException, IllegalBindingException, 
00490             IllegalLifeCycleException {
00491         
00492         if (isPrimitive()) {
00493             
00494             BindingController user_binding_controller = (BindingController) ((ProActiveComponent) getFcItfOwner()).getReferenceOnBaseObject();
00495             if (Utils.isGathercastItf(
00496                         (Interface) user_binding_controller.lookupFc(
00497                             clientItfName))) {
00498                 ProActiveInterface sItf = (ProActiveInterface) user_binding_controller.lookupFc(clientItfName);
00499                 Fractive.getGathercastController((ProActiveComponent) (sItf).getFcItfOwner())
00500                         .removedBindingOnServerItf(sItf.getFcItfName(),
00501                     (ProActiveComponent) sItf.getFcItfOwner(), clientItfName);
00502             }
00503             user_binding_controller.unbindFc(clientItfName);
00504         } else {
00505             checkUnbindability(clientItfName);
00506         }
00507         removeBinding(clientItfName);
00508     }
00509 
00517     public String[] listFc() {
00518         if (isPrimitive()) {
00519             return ((BindingController) ((ProActiveComponent) getFcItfOwner()).getReferenceOnBaseObject()).listFc();
00520         }
00521 
00522         InterfaceType[] itfs_types = ((ComponentType) getFcItfOwner().getFcType()).getFcInterfaceTypes();
00523         List client_itfs_names = new ArrayList();
00524 
00525         for (int i = 0; i < itfs_types.length; i++) {
00526             if (itfs_types[i].isFcClientItf()) {
00527                 if (itfs_types[i].isFcCollectionItf()) {
00528                     List collection_itfs = (List) bindings.get(itfs_types[i].getFcItfName());
00529 
00530                     if (collection_itfs != null) {
00531                         Iterator it = collection_itfs.iterator();
00532 
00533                         while (it.hasNext()) {
00534                             client_itfs_names.add(((Interface) it.next()).getFcItfName());
00535                         }
00536                     }
00537                 } else {
00538                     client_itfs_names.add(itfs_types[i].getFcItfName());
00539                 }
00540             }
00541         }
00542 
00543         return (String[]) client_itfs_names.toArray(new String[client_itfs_names.size()]);
00544     }
00545 
00546     protected boolean existsBinding(String clientItfName)
00547         throws NoSuchInterfaceException {
00548         if (isPrimitive() &&
00549                 !(((ProActiveInterfaceType) ((ComponentType) owner.getFcType()).getFcInterfaceType(
00550                     clientItfName)).isFcMulticastItf())) {
00551             return (((BindingController) ((ProActiveComponent) getFcItfOwner()).getReferenceOnBaseObject()).lookupFc(clientItfName) != null);
00552         } else {
00553             return bindings.containsBindingOn(clientItfName);
00554         }
00555     }
00556 
00557     protected void checkClientInterfaceName(String clientItfName)
00558         throws NoSuchInterfaceException {
00559         if (Utils.hasSingleCardinality(clientItfName, owner)) {
00560             return;
00561         }
00562 
00563         if (Utils.pertainsToACollectionInterface(clientItfName, owner) != null) {
00564             return;
00565         }
00566 
00567         if (Utils.isMulticastItf(clientItfName, owner)) {
00568             return;
00569         }
00570 
00571         throw new NoSuchInterfaceException(clientItfName +
00572             " does not correspond to a single nor a collective interface");
00573     }
00574 
00575     public Boolean isBound() {
00576         String[] client_itf_names = listFc();
00577 
00578         for (int i = 0; i < client_itf_names.length; i++) {
00579             try {
00580                 if (existsBinding(client_itf_names[i])) {
00581                     return true;
00582                 }
00583             } catch (NoSuchInterfaceException logged) {
00584                 controllerLogger.error("cannot find interface " +
00585                     client_itf_names[i] + " : " + logged.getMessage());
00586             }
00587         }
00588 
00589         return new Boolean(false);
00590     }
00591 }