org/objectweb/proactive/core/component/controller/ProActiveBindingControllerImpl.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.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; // key = clientInterfaceName ; value = Binding
00082 
00083     //    private Map<String, Map<ProActiveComponent, List<String>>> bindingsOnServerItfs = new HashMap<String, Map<ProActiveComponent,List<String>>>(0);
00084 
00085     // Map(serverItfName, Map(owner, clientItfName))
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         // TODO_M handle internal interfaces
00121         // if (server_itf_type.isFcClientItf()) {
00122         // throw new IllegalBindingException("cannot bind client interface " +
00123         // clientItfName + " to other client interface "
00124         // +server_itf_type.getFcItfName() );
00125         // }
00126         // if (!client_itf_type.isFcClientItf()) {
00127         // throw new IllegalBindingException("cannot bind client interface " +
00128         // clientItfName + " to other client interface "
00129         // +server_itf_type.getFcItfName() );
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         // multicast interfaces : interfaces must be compatible
00138         // (rem : itf is null when it is a single itf not yet bound
00139         if (Utils.isMulticastItf(clientItfName, getFcItfOwner())) {
00140             Fractive.getMulticastController(owner)
00141                     .ensureCompatibility(clientItfType,
00142                 (ProActiveInterface) serverItf);
00143 
00144             // ensure multicast interface of primitive component is initialized
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         //  TODO type checkings for other cardinalities
00163         else if (Utils.isSingletonItf(clientItfName, getFcItfOwner())) {
00164             InterfaceType sType = (InterfaceType) serverItf.getFcItfType();
00165 
00166             //InterfaceType cType = (InterfaceType)((ProActiveInterface)owner.getFcInterface(clientItfName)).getFcItfType();
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         // check for binding primitive component can only be performed in the
00185         // primitive component
00186         if (!isPrimitive()) {
00187             // removed the following checkings as they did not consider composite server itfs
00188             //            checkClientInterfaceName(clientItfName);
00189             if (existsBinding(clientItfName)) {
00190                 if (!((ProActiveInterfaceTypeImpl) ((Interface) getFcItfOwner()
00191                                                                         .getFcInterface(clientItfName)).getFcItfType()).isFcCollectionItf()) {
00192                     // binding from a single client interface : only 1 binding
00193                     // is allowed
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                     // binding from a collection interface
00202                     if (((InterfaceType) serverItf.getFcItfType()).isFcClientItf()) {
00203                         // binding to a client(external) interface --> not OK
00204                         throw new IllegalBindingException(serverItf.getFcItfName() +
00205                             " is not a server interface");
00206                     }
00207                 }
00208             }
00209         }
00210 
00211         // TODO_M : check bindings between external client interfaces
00212         // see next, but need to consider internal interfaces (i.e. valid if
00213         // server AND internal)
00214         // TODO_M : check bindings crossing composite membranes
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         // get value of (eventual) future before casting
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         // if output interceptors are defined
00308         // TODO_M check with groups : interception is here done at the beginning
00309         // of the group invocation,
00310         // not for each element of the group
00311         List outputInterceptors = ((ProActiveComponentImpl) getFcItfOwner()).getOutputInterceptors();
00312 
00313         if (!outputInterceptors.isEmpty()) {
00314             try {
00315                 // replace server itf with an interface of the same type+same proxy, but with interception code
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         // Multicast bindings are handled here
00332         if (Utils.isMulticastItf(clientItfName, owner)) {
00333             if (Utils.isGathercastItf(sItf)) {
00334                 //                Fractive.getMulticastController(owner)
00335                 //                .bindFcMulticast(clientItfName, getGathercastAdaptor(clientItfName, serverItf, sItf));
00336                 // no adaptor here
00337                 Fractive.getMulticastController(owner)
00338                         .bindFcMulticast(clientItfName, sItf);
00339                 // add a callback ref in the server gather interface
00340                 // TODO should throw a binding event
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             // binding operation is delegated
00354             ProActiveInterfaceType sItfType = ((ProActiveInterfaceType) sItf.getFcItfType());
00355 
00356             if (Utils.isGathercastItf(sItf)) {
00357                 primitiveBindFc(clientItfName,
00358                     getGathercastAdaptor(clientItfName, serverItf, sItf));
00359                 // add a callback ref in the server gather interface
00360                 // TODO should throw a binding event
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         // composite or parallel
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                 // add a callback ref in the server gather interface
00381                 // TODO should throw a binding event
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         // add an adaptor proxy for matching interface types
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         // delegate binding operation to the reified object
00427         BindingController user_binding_controller = (BindingController) ((ProActiveComponent) getFcItfOwner()).getReferenceOnBaseObject();
00428 
00429         // serverItf cannot be a Future (because it has to be casted) => make
00430         // sure if binding to a composite's internal interface
00431         serverItf = (ProActiveInterface) ProActive.getFutureValue(serverItf);
00432         user_binding_controller.bindFc(clientItfName, serverItf);
00433         //        addBinding(new Binding(clientItf, clientItfName, serverItf));
00434     }
00435 
00436     /*
00437      * binding method enforcing Interface type for the server interface, for
00438      * composite components
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         // TODO remove this as we should now use multicast interfaces for this purpose
00448         // if we have a collection interface, the impl object is actually a
00449         // group of references to interfaces
00450         // Thus we have to add the link to the new interface in this group
00451         // same for client interfaces of parallel components
00452         if (clientItfType.getFcItfName().equals(clientItfName)) {
00453             //            if ((isParallel() && !clientItfType.isFcClientItf())) {
00454             //                // collective binding, unnamed interface
00455             //                // TODO provide a default name?
00456             //                Group itf_group = ProActiveGroup.getGroup(clientItf.getFcItfImpl());
00457             //                itf_group.add(serverItf);
00458             //            } else {
00459             // single binding
00460             clientItf.setFcItfImpl(serverItf);
00461             //            }
00462         } else {
00463             if (Utils.getItfType(clientItfName, owner).isFcCollectionItf()) {
00464                 clientItf.setFcItfImpl(serverItf);
00465             } else {
00466                 //            if ((isParallel() && !clientItfType.isFcClientItf())) {
00467                 //                      
00468                 //                Group itf_group = ProActiveGroup.getGroup(clientItf.getFcItfImpl());
00469                 //                itf_group.addNamedElement(clientItfName, serverItf);
00470                 //            } else {
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      * @see org.objectweb.fractal.api.control.BindingController#unbindFc(String)
00482      *
00483      * CAREFUL : unbinding action on collective interfaces will remove all the
00484      * bindings to this interface. This is also the case when removing bindings
00485      * from the server interface of a parallel component (yes you can do
00486      * unbindFc(parallelServerItfName) !)
00487      */
00488     public void unbindFc(String clientItfName)
00489         throws NoSuchInterfaceException, IllegalBindingException, 
00490             IllegalLifeCycleException {
00491         // remove from bindings and set impl object to null
00492         if (isPrimitive()) {
00493             // delegate to primitive component
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 }

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