Orocos Real-Time Toolkit  2.5.0
TaskContextProxy.cpp
00001 /***************************************************************************
00002   tag: Peter Soetens  Wed Jan 18 14:09:49 CET 2006  TaskContextProxy.cxx
00003 
00004                         TaskContextProxy.cxx -  description
00005                            -------------------
00006     begin                : Wed January 18 2006
00007     copyright            : (C) 2006 Peter Soetens
00008     email                : peter.soetens@fmtc.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037 
00038 #include "TaskContextProxy.hpp"
00039 #include "TaskContextServer.hpp"
00040 #include "TaskContextC.h"
00041 #include "CorbaOperationCallerFactory.hpp"
00042 #include "CorbaLib.hpp"
00043 #include "OperationCallerProxy.hpp"
00044 
00045 #include "../../types/Types.hpp"
00046 #include "../../extras/SequentialActivity.hpp"
00047 #include "corba.h"
00048 #ifdef CORBA_IS_TAO
00049 #include "tao/TimeBaseC.h"
00050 #include "tao/Messaging/Messaging.h"
00051 #include "tao/Messaging/Messaging_RT_PolicyC.h"
00052 #include "orbsvcs/CosNamingC.h"
00053 #include <ace/String_Base.h>
00054 #else
00055 #include <omniORB4/Naming.hh>
00056 #endif
00057 #include <iostream>
00058 #include <fstream>
00059 #include <string>
00060 
00061 #include "RemotePorts.hpp"
00062 
00063 using namespace std;
00064 using namespace RTT::detail;
00065 
00066 namespace RTT
00067 {namespace corba
00068 {
00069     IllegalServer::IllegalServer() : reason("This server does not exist or has the wrong type.") {}
00070 
00071     IllegalServer::IllegalServer(const std::string& r) : reason(r) {}
00072 
00073     IllegalServer::~IllegalServer() throw() {}
00074 
00075     const char* IllegalServer::what() const throw() { return reason.c_str(); }
00076 
00077 
00078     std::map<TaskContextProxy*, corba::CTaskContext_ptr> TaskContextProxy::proxies;
00079 
00080     PortableServer::POA_var TaskContextProxy::proxy_poa;
00081 
00082     TaskContextProxy::~TaskContextProxy()
00083     {
00084         log(Info) << "Terminating TaskContextProxy for " <<  this->getName() <<endlog();
00085         if ( this->properties() ) {
00086             deletePropertyBag( *this->properties() );
00087         }
00088         this->attributes()->clear();
00089         for (list<PortInterface*>::iterator it = port_proxies.begin(); it != port_proxies.end(); ++it)
00090             delete *it;
00091         proxies.erase(this);
00092     }
00093 
00094     TaskContextProxy::TaskContextProxy(std::string name, bool is_ior)
00095         : TaskContext("NotFound")
00096     {
00097         Logger::In in("TaskContextProxy");
00098         this->clear();
00099         this->setActivity( new SequentialActivity() );
00100         try {
00101             if (is_ior) {
00102                 // Use the first argument to create the task object reference,
00103                 // in real applications we use the naming service, but let's do
00104                 // the easy part first!
00105                 CORBA::Object_var task_object =
00106                     orb->string_to_object ( name.c_str() );
00107 
00108                 // Now downcast the object reference to the appropriate type
00109                 mtask = corba::CTaskContext::_narrow (task_object.in ());
00110             } else {
00111                 // NameService
00112                 CORBA::Object_var rootObj;
00113                 CosNaming::NamingContext_var rootContext;
00114                 try {
00115                     rootObj = orb->resolve_initial_references("NameService");
00116                     rootContext = CosNaming::NamingContext::_narrow(rootObj);
00117                 } catch (...) {}
00118 
00119                 if (CORBA::is_nil(rootContext)) {
00120                     std::string err("TaskContextProxy could not acquire NameService.");
00121                     log(Error) << err <<endlog();
00122                     throw IllegalServer(err);
00123                 }
00124                 Logger::log() <<Logger::Debug << "TaskContextProxy found CORBA NameService."<<endlog();
00125                 CosNaming::Name serverName;
00126                 serverName.length(2);
00127                 serverName[0].id = CORBA::string_dup("TaskContexts");
00128                 serverName[1].id = CORBA::string_dup( name.c_str() );
00129 
00130                 // Get object reference
00131                 CORBA::Object_var task_object = rootContext->resolve(serverName);
00132                 mtask = corba::CTaskContext::_narrow (task_object.in ());
00133             }
00134             if ( CORBA::is_nil( mtask ) ) {
00135                 std::string err("Failed to acquire TaskContextServer '"+name+"'.");
00136                 Logger::log() << Logger::Error << err <<endlog();
00137                 throw IllegalServer(err);
00138             }
00139             CORBA::String_var nm = mtask->getName(); // force connect to object.
00140             std::string newname( nm.in() );
00141             this->provides()->setName( newname );
00142             Logger::log() << Logger::Info << "Successfully connected to TaskContextServer '"+newname+"'."<<endlog();
00143             proxies[this] = mtask.in();
00144         }
00145         catch (CORBA::Exception &e) {
00146             log(Error)<< "CORBA exception raised when resolving Object !" << endlog();
00147             Logger::log() << CORBA_EXCEPTION_INFO(e) << endlog();
00148             throw;
00149         }
00150         catch (IllegalServer& e) {
00151             // rethrow
00152             throw e;
00153         }
00154         catch (...) {
00155             log(Error) <<"Unknown Exception in TaskContextProxy construction!"<<endlog();
00156             throw;
00157         }
00158 
00159         this->synchronize();
00160     }
00161 
00162     TaskContextProxy::TaskContextProxy( ::RTT::corba::CTaskContext_ptr taskc)
00163         : TaskContext("CORBAProxy"), mtask( corba::CTaskContext::_duplicate(taskc) )
00164     {
00165         Logger::In in("TaskContextProxy");
00166         this->clear();
00167         // We can't use setActivity() since that would check isRunning() first.
00168         this->forceActivity( new SequentialActivity );
00169         try {
00170             CORBA::String_var nm = mtask->getName(); // force connect to object.
00171             std::string name( nm.in() );
00172             this->provides()->setName( name );
00173             proxies[this] = mtask.in();
00174         }
00175         catch (CORBA::Exception &e) {
00176             log(Error) << "CORBA exception raised when creating TaskContextProxy!" << Logger::nl;
00177             Logger::log() << CORBA_EXCEPTION_INFO(e) << endlog();
00178         }
00179         catch (...) {
00180             throw;
00181         }
00182         this->synchronize();
00183     }
00184 
00185     void TaskContextProxy::synchronize()
00186     {
00187         // Add here the interfaces that need to be synchronised every time a lookup is done.
00188         // Detect already added parts of an interface, does not yet detect removed parts...
00189         if (CORBA::is_nil(mtask))
00190             return;
00191 
00192         log(Debug) << "Fetching Ports."<<endlog();
00193         CDataFlowInterface_var dfact = mtask->ports();
00194         TypeInfoRepository::shared_ptr type_repo = TypeInfoRepository::Instance();
00195         if (dfact) {
00196             CDataFlowInterface::CPortDescriptions_var objs = dfact->getPortDescriptions();
00197             for ( size_t i=0; i < objs->length(); ++i) {
00198                 CPortDescription port = objs[i];
00199                 if (this->ports()->getPort( port.name.in() ))
00200                     continue; // already added.
00201 
00202                 TypeInfo const* type_info = type_repo->type(port.type_name.in());
00203                 if (!type_info)
00204                 {
00205                     log(Warning) << "remote port " << port.name
00206                         << " has a type that cannot be marshalled over CORBA: " << port.type_name << ". "
00207                         << "It is ignored by TaskContextProxy" << endlog();
00208                 }
00209                 else
00210                 {
00211                     PortInterface* new_port;
00212                     if (port.type == RTT::corba::CInput)
00213                         new_port = new RemoteInputPort( type_info, dfact.in(), port.name.in(), ProxyPOA() );
00214                     else
00215                         new_port = new RemoteOutputPort( type_info, dfact.in(), port.name.in(), ProxyPOA() );
00216 
00217                     this->ports()->addPort(*new_port);
00218                     port_proxies.push_back(new_port); // see comment in definition of port_proxies
00219                 }
00220             }
00221         }
00222 
00223         CService_var serv = mtask->getProvider("this");
00224         this->fetchServices(this->provides(), serv.in() );
00225 
00226         CServiceRequester_var srq = mtask->getRequester("this");
00227         this->fetchRequesters(this->requires(), srq.in() );
00228         log(Debug) << "All Done."<<endlog();
00229     }
00230 
00231     void TaskContextProxy::fetchRequesters(ServiceRequester* parent, CServiceRequester_ptr csrq)
00232     {
00233         COperationCallerNames_var opcnames = csrq->getOperationCallerNames();
00234 
00235         log(Debug) << "Fetching OperationCallers of " << parent->getRequestName()<<endlog();
00236         for ( size_t i=0; i < opcnames->length(); ++i) {
00237             if ( parent->getOperationCaller( string(opcnames[i].in() )))
00238                 continue; // already added.
00239             log(Debug) << "Requiring operation: "<< opcnames[i].in() <<endlog();
00240             parent->addOperationCaller( * new OperationCallerProxy(string(opcnames[i].in() ), CServiceRequester::_duplicate(csrq) ));
00241         }
00242 
00243         CRequestNames_var rqlist = csrq->getRequestNames();
00244 
00245         for( size_t i =0; i != rqlist->length(); ++i) {
00246             if ( string( rqlist[i] ) == "this")
00247                 continue;
00248             CServiceRequester_var cobj = csrq->getRequest(rqlist[i]);
00249 
00250             ServiceRequester* tobj = this->requires(std::string(rqlist[i]));
00251 
00252             // Recurse:
00253             this->fetchRequesters( tobj, cobj.in() );
00254         }
00255     }
00256 
00257     // Recursively fetch remote objects and create local proxies.
00258     void TaskContextProxy::fetchServices(Service::shared_ptr parent, CService_ptr serv)
00259     {
00260         log(Debug) << "Fetching "<<parent->getName()<<" Service:"<<endlog();
00261         // load command and method factories.
00262         // methods:
00263         log(Debug) << "Fetching Operations."<<endlog();
00264         COperationInterface::COperationList_var objs;
00265         objs = serv->getOperations();
00266         for ( size_t i=0; i < objs->length(); ++i) {
00267             if ( parent->hasMember( string(objs[i].in() )))
00268                 continue; // already added.
00269             log(Debug) << "Providing operation: "<< objs[i].in() <<endlog();
00270             parent->add( objs[i].in(), new CorbaOperationCallerFactory( objs[i].in(), serv, ProxyPOA() ) );
00271         }
00272 
00273         // first do properties:
00274         log(Debug) << "Fetching Properties."<<endlog();
00275         // a dot-separated list of subbags and items
00276         CConfigurationInterface::CPropertyNames_var props = serv->getPropertyList();
00277 
00278         for (size_t i=0; i != props->length(); ++i) {
00279             if ( findProperty( *parent->properties(), string(props[i].name.in()), "." ) )
00280                 continue; // previously added.
00281             if ( !serv->hasProperty( props[i].name.in() ) ) {
00282                 log(Error) <<"Property "<< string(props[i].name.in()) << " present in getPropertyList() but not accessible."<<endlog();
00283                 continue;
00284             }
00285            // If the type is known, immediately build the correct property and datasource.
00286             CORBA::String_var tn = serv->getPropertyTypeName(props[i].name.in());
00287             TypeInfo* ti = TypeInfoRepository::Instance()->type( tn.in() );
00288 
00289             // decode the prefix and property name from the given name:
00290             string pname = string( props[i].name.in() );
00291             pname = pname.substr( pname.rfind(".") + 1 );
00292             string prefix = string( props[i].name.in() );
00293             if ( prefix.rfind(".") == string::npos ) {
00294                 prefix.clear();
00295             }
00296             else {
00297                 prefix = prefix.substr( 0, prefix.rfind(".") );
00298             }
00299 
00300             if ( ti && ti->hasProtocol(ORO_CORBA_PROTOCOL_ID)) {
00301                 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>(ti->getProtocol(ORO_CORBA_PROTOCOL_ID));
00302                 assert(ctt);
00303                 // data source needs full remote path name
00304                 DataSourceBase::shared_ptr ds = ctt->createPropertyDataSource( serv, props[i].name.in() );
00305                 storeProperty( *parent->properties(), prefix, ti->buildProperty( pname, props[i].description.in(), ds));
00306                 log(Debug) << "Looked up Property " << tn.in() << " "<< pname <<": created."<<endlog();
00307             }
00308             else {
00309                 if ( string("PropertyBag") == tn.in() ) {
00310                     storeProperty(*parent->properties(), prefix, new Property<PropertyBag>( pname, props[i].description.in()) );
00311                     log(Debug) << "Looked up PropertyBag " << tn.in() << " "<< pname <<": created."<<endlog();
00312                 } else
00313                     log(Error) << "Looked up Property " << tn.in() << " "<< pname <<": type not known. Check your RTT_COMPONENT_PATH."<<endlog();
00314             }
00315         }
00316 
00317         log(Debug) << "Fetching Attributes."<<endlog();
00318         CConfigurationInterface::CAttributeNames_var attrs = serv->getAttributeList();
00319         for (size_t i=0; i != attrs->length(); ++i) {
00320             if ( parent->hasAttribute( string(attrs[i].in()) ) )
00321                 continue; // previously added.
00322             if ( !serv->hasAttribute( attrs[i].in() ) ) {
00323                 log(Error) <<"Attribute '"<< string(attrs[i].in()) << "' present in getAttributeList() but not accessible."<<endlog();
00324                 continue;
00325             }
00326             // If the type is known, immediately build the correct attribute and datasource,
00327             CORBA::String_var tn = serv->getAttributeTypeName( attrs[i].in() );
00328             TypeInfo* ti = TypeInfoRepository::Instance()->type( tn.in() );
00329             if ( ti && ti->hasProtocol(ORO_CORBA_PROTOCOL_ID) ) {
00330                 log(Debug) << "Looking up Attribute " << tn.in() <<": found!"<<endlog();
00331                 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>(ti->getProtocol(ORO_CORBA_PROTOCOL_ID));
00332                 assert(ctt);
00333                 // this function should check itself for const-ness of the remote Attribute:
00334                 DataSourceBase::shared_ptr ds = ctt->createAttributeDataSource( serv, attrs[i].in() );
00335                 if ( serv->isAttributeAssignable( attrs[i].in() ) )
00336                     parent->setValue( ti->buildAttribute( attrs[i].in(), ds));
00337                 else
00338                     parent->setValue( ti->buildConstant( attrs[i].in(), ds));
00339             } else {
00340                 log(Error) << "Looking up Attribute " << tn.in();
00341                 Logger::log() <<": type not known. Check your RTT_COMPONENT_PATH."<<endlog();
00342             }
00343         }
00344 
00345         CService::CProviderNames_var plist = serv->getProviderNames();
00346 
00347         for( size_t i =0; i != plist->length(); ++i) {
00348             if ( string( plist[i] ) == "this")
00349                 continue;
00350             CService_var cobj = serv->getService(plist[i]);
00351             CORBA::String_var descr = cobj->getServiceDescription();
00352 
00353             Service::shared_ptr tobj = parent->provides(std::string(plist[i]));
00354             tobj->doc( descr.in() );
00355 
00356             // Recurse:
00357             this->fetchServices( tobj, cobj.in() );
00358         }
00359     }
00360 
00361     void TaskContextProxy::DestroyOrb()
00362     {
00363         try {
00364             // Destroy the POA, waiting until the destruction terminates
00365             //poa->destroy (1, 1);
00366             if (orb) {
00367                 orb->destroy();
00368                 rootPOA = 0;
00369                 orb = 0;
00370                 std::cerr <<"Orb destroyed."<<std::endl;
00371             }
00372         }
00373         catch (CORBA::Exception &e) {
00374             log(Error) << "Orb Init : CORBA exception raised!" << Logger::nl;
00375             Logger::log() << CORBA_EXCEPTION_INFO(e) << endlog();
00376         }
00377     }
00378 
00379     TaskContextProxy* TaskContextProxy::Create(std::string name, bool is_ior /*=false*/) {
00380         if ( CORBA::is_nil(orb) ) {
00381             log(Error) << "Won't create a proxy for '"<<name<<"' : orb is nill. Call TaskContextProxy::InitOrb(argc, argv); before TaskContextProxy::Create()." <<endlog();
00382             return 0;
00383         }
00384         if ( name.empty() ) {
00385             log(Error) << "Can't create a proxy with an empty name." <<endlog();
00386             return 0;
00387         }
00388         // create new:
00389         try {
00390             TaskContextProxy* ctp = new TaskContextProxy( name, is_ior );
00391             return ctp;
00392         }
00393         catch( IllegalServer& is ) {
00394             cerr << is.what() << endl;
00395         }
00396         return 0;
00397     }
00398 
00399     TaskContextProxy* TaskContextProxy::CreateFromFile(std::string name) {
00400         if ( CORBA::is_nil(orb) ) {
00401             log(Error) << "Won't create a proxy for '"<<name<<"' : orb is nill. Call TaskContextProxy::InitOrb(argc, argv); before TaskContextProxy::Create()." <<endlog();
00402             return 0;
00403         }
00404         if ( name.empty() ) {
00405             log(Error) << "Can't create a proxy with an empty file name." <<endlog();
00406             return 0;
00407         }
00408 
00409         // create new:
00410         ifstream namestream( name.c_str() );
00411         string ior;
00412         namestream >> ior;
00413         return Create( ior, true);
00414     }
00415 
00416     TaskContext* TaskContextProxy::Create(::RTT::corba::CTaskContext_ptr t, bool force_remote) {
00417         Logger::In in("TaskContextProxy::Create");
00418         if ( CORBA::is_nil(orb) ) {
00419             log(Error) << "Can not create proxy when ORB is nill !"<<endlog();
00420             return 0;
00421         }
00422         if ( CORBA::is_nil(t) ) {
00423             log(Error) << "Can not create proxy for nill peer !" <<endlog();
00424             return 0;
00425         }
00426 
00427         // proxy present for this object ?
00428         // is_equivalent is actually our best try.
00429         for (PMap::iterator it = proxies.begin(); it != proxies.end(); ++it)
00430             if ( (it->second)->_is_equivalent( t ) ) {
00431                 log(Debug) << "Existing proxy found !" <<endlog();
00432                 return it->first;
00433             }
00434 
00435         // Check if the CTaskContext is actually a local TaskContext
00436         if (! force_remote)
00437         {
00438             for (TaskContextServer::ServerMap::iterator it = TaskContextServer::servers.begin(); it != TaskContextServer::servers.end(); ++it)
00439                 if ( it->second->server()->_is_equivalent( t ) ) {
00440                     log(Debug) << "Local server found !" <<endlog();
00441                     return it->first;
00442                 }
00443         }
00444 
00445         log(Debug) << "No local taskcontext found..." <<endlog();
00446         // create new:
00447         try {
00448             TaskContextProxy* ctp = new TaskContextProxy( t );
00449             return ctp;
00450         }
00451         catch( IllegalServer& is ) {
00452             cerr << is.what() << endl;
00453         }
00454         return 0;
00455     }
00456 
00457     bool TaskContextProxy::start() {
00458         try {
00459             if (! CORBA::is_nil(mtask) )
00460                 return mtask->start();
00461         } catch(...) {
00462             mtask = CTaskContext::_nil();
00463             this->setName("NotFound");
00464             this->clear();
00465         }
00466         return false;
00467     }
00468 
00469     bool TaskContextProxy::stop() {
00470         try {
00471             if (! CORBA::is_nil(mtask) )
00472                 return mtask->stop();
00473         } catch(...) {
00474             mtask = CTaskContext::_nil();
00475             this->setName("NotFound");
00476             this->clear();
00477         }
00478         return false;
00479     }
00480 
00481     bool TaskContextProxy::activate() {
00482         try {
00483             if (! CORBA::is_nil(mtask) )
00484                 return mtask->activate();
00485         } catch(...) {
00486             mtask = CTaskContext::_nil();
00487             this->setName("NotFound");
00488             this->clear();
00489         }
00490         return false;
00491     }
00492 
00493     bool TaskContextProxy::isActive() const {
00494         try {
00495             if (! CORBA::is_nil(mtask) )
00496                 return mtask->isActive();
00497         } catch(...) {
00498             mtask = CTaskContext::_nil();
00499         }
00500         return false;
00501     }
00502 
00503     bool TaskContextProxy::isRunning() const {
00504         try {
00505             if (! CORBA::is_nil(mtask) )
00506                 return mtask->isRunning();
00507         } catch(...) {
00508             mtask = CTaskContext::_nil();
00509         }
00510         return false;
00511     }
00512 
00513     bool TaskContextProxy::configure() {
00514         try {
00515             if (! CORBA::is_nil(mtask) )
00516                 return mtask->configure();
00517         } catch(...) {
00518             mtask = CTaskContext::_nil();
00519             this->setName("NotFound");
00520             this->clear();
00521         }
00522         return false;
00523     }
00524 
00525     bool TaskContextProxy::cleanup() {
00526         try {
00527             if (! CORBA::is_nil(mtask) )
00528                 return mtask->cleanup();
00529         } catch(...) {
00530             mtask = CTaskContext::_nil();
00531             this->setName("NotFound");
00532             this->clear();
00533         }
00534         return false;
00535     }
00536 
00537     bool TaskContextProxy::isConfigured() const {
00538         try {
00539             if (! CORBA::is_nil(mtask) )
00540                 return mtask->isConfigured();
00541         } catch(...) {
00542             mtask = CTaskContext::_nil();
00543         }
00544         return false;
00545     }
00546 
00547     bool TaskContextProxy::inFatalError() const {
00548         try {
00549             if (! CORBA::is_nil(mtask) )
00550                 return mtask->inFatalError();
00551         } catch(...) {
00552             mtask = CTaskContext::_nil();
00553         }
00554         return false;
00555     }
00556 
00557     bool TaskContextProxy::inRunTimeError() const {
00558         try {
00559             if (! CORBA::is_nil(mtask) )
00560                 return mtask->inRunTimeError();
00561         } catch(...) {
00562             mtask = CTaskContext::_nil();
00563         }
00564         return false;
00565     }
00566 
00567     TaskContext::TaskState TaskContextProxy::getTaskState() const {
00568         try {
00569             if (! CORBA::is_nil(mtask) )
00570                 return TaskContext::TaskState( mtask->getTaskState() );
00571         } catch(...) {
00572             mtask = CTaskContext::_nil();
00573         }
00574         return TaskContext::Init;
00575     }
00576 
00577     void TaskContextProxy::setName(const std::string& n)
00578     {
00579         //mtask->setName( n.c_str() );
00580     }
00581 
00582     bool TaskContextProxy::addPeer( TaskContext* peer, std::string alias /*= ""*/ )
00583     {
00584         try {
00585             if (CORBA::is_nil(mtask))
00586                 return false;
00587 
00588             // if peer is a proxy, add the proxy, otherwise, create new server.
00589             TaskContextProxy* ctp = dynamic_cast<TaskContextProxy*>( peer );
00590             if (ctp) {
00591                 if ( mtask->addPeer( ctp->server(), alias.c_str() ) ) {
00592                     this->synchronize();
00593                     return true;
00594                 }
00595                 return false;
00596             }
00597             // no server yet, create it.
00598             TaskContextServer* newpeer = TaskContextServer::Create(peer);
00599             if ( mtask->addPeer( newpeer->server(), alias.c_str() ) ) {
00600                 this->synchronize();
00601                 return true;
00602             }
00603         } catch(...) {
00604             mtask = CTaskContext::_nil();
00605             this->setName("NotFound");
00606             this->clear();
00607         }
00608         return false;
00609     }
00610 
00611     void TaskContextProxy::removePeer( const std::string& name )
00612     {
00613         try {
00614             if (CORBA::is_nil(mtask))
00615                 return;
00616             mtask->removePeer( name.c_str() );
00617         } catch(...) {
00618             mtask = CTaskContext::_nil();
00619             this->setName("NotFound");
00620             this->clear();
00621         }
00622     }
00623 
00624     void TaskContextProxy::removePeer( TaskContext* peer )
00625     {
00626         try {
00627             if (CORBA::is_nil(mtask))
00628                 return;
00629             mtask->removePeer( peer->getName().c_str() );
00630         } catch(...) {
00631             mtask = CTaskContext::_nil();
00632             this->setName("NotFound");
00633             this->clear();
00634         }
00635     }
00636 
00637     bool TaskContextProxy::connectPeers( TaskContext* peer )
00638     {
00639         try {
00640             if (CORBA::is_nil(mtask))
00641                 return false;
00642             TaskContextServer* newpeer = TaskContextServer::Create(peer);
00643             return mtask->connectPeers( newpeer->server() );
00644         } catch(...) {
00645             mtask = CTaskContext::_nil();
00646             this->setName("NotFound");
00647             this->clear();
00648         }
00649         return false;
00650     }
00651 
00652     void TaskContextProxy::disconnectPeers( const std::string& name )
00653     {
00654         try {
00655             if (! CORBA::is_nil(mtask) )
00656                 mtask->disconnectPeers( name.c_str() );
00657         } catch(...) {
00658             mtask = CTaskContext::_nil();
00659             this->setName("NotFound");
00660             this->clear();
00661         }
00662     }
00663 
00664     TaskContext::PeerList TaskContextProxy::getPeerList() const
00665     {
00666 
00667         TaskContext::PeerList vlist;
00668         try {
00669             if (! CORBA::is_nil(mtask) ) {
00670                 corba::CTaskContext::CPeerNames_var plist = mtask->getPeerList();
00671                 for( size_t i =0; i != plist->length(); ++i)
00672                     vlist.push_back( std::string( plist[i] ) );
00673             }
00674         } catch(...) {
00675             mtask = CTaskContext::_nil();
00676         }
00677         return vlist;
00678     }
00679 
00680     bool TaskContextProxy::hasPeer( const std::string& peer_name ) const
00681     {
00682         try {
00683             if (! CORBA::is_nil(mtask))
00684                 return mtask->hasPeer( peer_name.c_str() );
00685         } catch(...) {
00686             mtask = CTaskContext::_nil();
00687         }
00688         return false;
00689     }
00690 
00691     TaskContext* TaskContextProxy::getPeer(const std::string& peer_name ) const
00692     {
00693         try {
00694             if (CORBA::is_nil(mtask))
00695                 return 0;
00696             corba::CTaskContext_ptr ct = mtask->getPeer( peer_name.c_str() );
00697             if ( CORBA::is_nil(ct) )
00698                 return 0;
00699             return TaskContextProxy::Create( ct );
00700         } catch(...) {
00701             mtask = CTaskContext::_nil();
00702         }
00703         return 0;
00704     }
00705 
00706     bool TaskContextProxy::connectPorts( TaskContext* peer )
00707     {
00708         try {
00709             if (CORBA::is_nil(mtask))
00710                 return false;
00711             TaskContextServer* newpeer = TaskContextServer::Create(peer);
00712             return mtask->connectPorts( newpeer->server() );
00713         } catch(...) {
00714             mtask = CTaskContext::_nil();
00715             this->setName("NotFound");
00716             this->clear();
00717         }
00718         return false;
00719     }
00720 
00721     bool TaskContextProxy::connectServices( TaskContext* peer )
00722     {
00723         try {
00724             if (CORBA::is_nil(mtask))
00725                 return false;
00726             TaskContextServer* newpeer = TaskContextServer::Create(peer);
00727             return mtask->connectServices( newpeer->server() );
00728         } catch(...) {
00729             mtask = CTaskContext::_nil();
00730             this->setName("NotFound");
00731             this->clear();
00732         }
00733         return false;
00734     }
00735 
00736     bool TaskContextProxy::ready()
00737     {
00738         if (CORBA::is_nil(mtask)) {
00739             this->clear();
00740             return false;
00741         }
00742         try {
00743             mtask->getName(); // basic check
00744             return true;
00745         } catch(...) {
00746             // we could also try to re-establish the connection in case of naming...
00747             this->clear();
00748             mtask = CTaskContext::_nil();
00749         }
00750         return false;
00751     }
00752 
00753     corba::CTaskContext_ptr TaskContextProxy::server() const {
00754         if ( CORBA::is_nil(mtask) )
00755             return CTaskContext::_nil();
00756         return mtask.in();
00757     }
00758 
00759     PortableServer::POA_ptr TaskContextProxy::ProxyPOA() {
00760         if ( CORBA::is_nil(orb) )
00761             return PortableServer::POA::_nil();
00762         if ( CORBA::is_nil(proxy_poa) ) {
00763             CORBA::Object_var poa_object =
00764                 orb->resolve_initial_references ("RootPOA");
00765 
00766             // new POA for the proxies:
00767             // Use default manager, is already activated !
00768             //PortableServer::POAManager_var proxy_manager = poa->the_POAManager ();
00769             //CORBA::PolicyList pol;
00770             //proxy_poa = poa->create_POA( "ProxyPOA", proxy_manager, pol );
00771             proxy_poa =
00772                 PortableServer::POA::_narrow (poa_object.in ());
00773         }
00774         // note: do not use _retn(): user must duplicate in constructor.
00775         return proxy_poa.in();
00776     }
00777 }}
00778