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
00032
00033
00034
00035
00036
00037
00055 #include "ControlTaskProxy.hpp"
00056 #include "ControlTaskServer.hpp"
00057 #include "ControlTaskC.h"
00058 #include "CorbaMethodFactory.hpp"
00059 #include "CorbaCommandFactory.hpp"
00060 #include "CORBAExpression.hpp"
00061 #include "ScriptingAccessProxy.hpp"
00062 #include "CorbaPort.hpp"
00063
00064 #include "CommandInterface.hpp"
00065 #include "Types.hpp"
00066 #include "orbsvcs/CosNamingC.h"
00067 #include <iostream>
00068
00069 #include <ace/String_Base.h>
00070
00071 using namespace std;
00072
00073 namespace RTT
00074 {namespace Corba
00075 {
00076 IllegalServer::IllegalServer() : reason("This server does not exist or has the wrong type.") {}
00077
00078 IllegalServer::~IllegalServer() throw() {}
00079
00080 const char* IllegalServer::what() const throw() { return reason.c_str(); }
00081
00082
00083 std::map<ControlTaskProxy*, Corba::ControlTask_ptr> ControlTaskProxy::proxies;
00084
00085 PortableServer::POA_var ControlTaskProxy::proxy_poa;
00086
00087 ControlTaskProxy::~ControlTaskProxy()
00088 {
00089 if ( this->properties() ) {
00090 flattenPropertyBag( *this->properties() );
00091 deleteProperties( *this->properties() );
00092 }
00093 this->attributes()->clear();
00094 }
00095
00096 ControlTaskProxy::ControlTaskProxy(std::string name, bool is_ior)
00097 : TaskContext("NotFound")
00098 {
00099 this->clear();
00100 try {
00101 if (is_ior) {
00102
00103
00104
00105 CORBA::Object_var task_object =
00106 orb->string_to_object ( name.c_str() );
00107
00108
00109 mtask = Corba::ControlTask::_narrow (task_object.in ());
00110 } else {
00111
00112 CORBA::Object_var rootObj = orb->resolve_initial_references("NameService");
00113 CosNaming::NamingContext_var rootContext = CosNaming::NamingContext::_narrow(rootObj.in());
00114 if (CORBA::is_nil(rootContext.in() )) {
00115 log(Error) << "ControlTaskProxy could not acquire NameService."<<endlog();
00116 throw IllegalServer();
00117 }
00118 Logger::log() <<Logger::Debug << "ControlTaskProxy found CORBA NameService."<<endlog();
00119 CosNaming::Name serverName;
00120 serverName.length(2);
00121 serverName[0].id = CORBA::string_dup("ControlTasks");
00122 serverName[1].id = CORBA::string_dup( name.c_str() );
00123
00124
00125 CORBA::Object_var task_object = rootContext->resolve(serverName);
00126 mtask = Corba::ControlTask::_narrow (task_object.in ());
00127 }
00128 if ( CORBA::is_nil( mtask.in() ) ) {
00129 Logger::log() << Logger::Error << "Failed to acquire ControlTaskServer '"+name+"'."<<endlog();
00130 throw IllegalServer();
00131 }
00132 CORBA::String_var nm = mtask->getName();
00133 std::string newname( nm.in() );
00134 this->mtask_name = newname;
00135 Logger::log() << Logger::Info << "Successfully connected to ControlTaskServer '"+newname+"'."<<endlog();
00136 proxies[this] = mtask;
00137 }
00138 catch (CORBA::Exception &e) {
00139 log(Error)<< "CORBA exception raised when resolving Object !" << endlog();
00140 Logger::log() << e._info().c_str() << endlog();
00141 }
00142 catch (...) {
00143 log(Error) <<"Unknown Exception in ControlTaskProxy construction!"<<endlog();
00144 throw;
00145 }
00146
00147 this->synchronizeOnce();
00148 }
00149
00150 ControlTaskProxy::ControlTaskProxy( ::RTT::Corba::ControlTask_ptr taskc)
00151 : TaskContext("CORBAProxy"), mtask( Corba::ControlTask::_duplicate(taskc) )
00152 {
00153 this->clear();
00154 try {
00155 CORBA::String_var nm = mtask->getName();
00156 std::string name( nm.in() );
00157 this->mtask_name = name;
00158 proxies[this] = mtask;
00159 }
00160 catch (CORBA::Exception &e) {
00161 log(Error) << "CORBA exception raised when creating ControlTaskProxy!" << Logger::nl;
00162 Logger::log() << e._info().c_str() << endlog();
00163 }
00164 catch (...) {
00165 throw;
00166 }
00167 this->synchronizeOnce();
00168 }
00169
00170 void ControlTaskProxy::synchronizeOnce()
00171 {
00172
00173 if (!mtask)
00174 return;
00175
00176 log(Debug) << "Fetching ScriptingAccess."<<endlog();
00177 Corba::ScriptingAccess_var saC = mtask->scripting();
00178 if ( saC ) {
00179 delete mscriptAcc;
00180 mscriptAcc = new ScriptingAccessProxy( saC.in() );
00181 }
00182
00183 this->synchronize();
00184 }
00185
00186 void ControlTaskProxy::synchronize()
00187 {
00188
00189
00190 if (!mtask)
00191 return;
00192
00193
00194
00195 log(Debug) << "Fetching Methods."<<endlog();
00196 MethodInterface_var mfact = mtask->methods();
00197 if (mfact) {
00198 MethodList_var objs;
00199 objs = mfact->getMethods();
00200 for ( size_t i=0; i < objs->length(); ++i) {
00201 if (this->methods()->hasMember( string(objs[i].in() )))
00202 continue;
00203 this->methods()->add( objs[i].in(), new CorbaMethodFactory( objs[i].in(), mfact.in(), ProxyPOA() ) );
00204 }
00205 }
00206
00207 log(Debug) << "Fetching Commands."<<endlog();
00208 CommandInterface_var cfact = mtask->commands();
00209 if (cfact) {
00210 CommandList_var objs;
00211 objs = cfact->getCommands();
00212 for ( size_t i=0; i < objs->length(); ++i) {
00213 if (this->commands()->hasMember( string(objs[i].in() )))
00214 continue;
00215 this->commands()->add( objs[i].in(), new CorbaCommandFactory( objs[i].in(), cfact.in(), ProxyPOA() ) );
00216 }
00217 }
00218
00219
00220 log(Debug) << "Fetching Properties."<<endlog();
00221 AttributeInterface::PropertyNames_var props = mtask->attributes()->getPropertyList();
00222
00223 for (size_t i=0; i != props->length(); ++i) {
00224 if ( this->attributes()->hasProperty( string(props[i].name.in()) ) )
00225 continue;
00226 Expression_var expr = mtask->attributes()->getProperty( props[i].name.in() );
00227 if ( CORBA::is_nil( expr ) ) {
00228 log(Error) <<"Property "<< string(props[i].name.in()) << " present in getPropertyList() but not accessible."<<endlog();
00229 continue;
00230 }
00231 #if 0 // This code may trigger endless recurse if server has recursive prop bags.
00232
00233
00234 CORBA::Any_var any = expr->get();
00235 PropertyBag bag;
00236 if ( AnyConversion<PropertyBag>::update( *any, bag ) ) {
00237 Property<PropertyBag>* pbag = new Property<PropertyBag>( string(props[i].name.in()), string(props[i].description.in()), bag);
00238 this->attributes()->addProperty( pbag );
00239 continue;
00240 }
00241 #endif
00242 AssignableExpression_var as_expr = AssignableExpression::_narrow( expr.in() );
00243
00244 if ( CORBA::is_nil( as_expr ) ) {
00245 log(Error) <<"Property "<< string(props[i].name.in()) << " was not writable !"<<endlog();
00246 } else {
00247
00248
00249 CORBA::String_var tn = as_expr->getTypeName();
00250 TypeInfo* ti = TypeInfoRepository::Instance()->type( tn.in() );
00251 Logger::log() <<Logger::Info << "Looking up Property " << tn.in();
00252 if ( ti && ti->getProtocol(ORO_CORBA_PROTOCOL_ID)) {
00253 this->attributes()->addProperty( ti->buildProperty( props[i].name.in(), props[i].description.in(),
00254 ti->getProtocol(ORO_CORBA_PROTOCOL_ID)->proxy( expr.in() ) ) );
00255 Logger::log() <<Logger::Info <<" found!"<<endlog();
00256 }
00257 else {
00258 this->attributes()->addProperty( new Property<CORBA::Any_ptr>( string(props[i].name.in()), string(props[i].description.in()), new CORBAAssignableExpression<Property<CORBA::Any_ptr>::DataSourceType>( as_expr.in() ) ) );
00259 Logger::log() <<Logger::Info<<" not found :-("<<endlog();
00260 }
00261 }
00262 }
00263
00264 log(Debug) << "Fetching Attributes."<<endlog();
00265
00266 AttributeInterface::AttributeNames_var attrs = mtask->attributes()->getAttributeList();
00267
00268 for (size_t i=0; i != attrs->length(); ++i) {
00269 if ( this->attributes()->hasAttribute( string(attrs[i].in()) ) )
00270 continue;
00271 Expression_var expr = mtask->attributes()->getAttribute( attrs[i].in() );
00272 if ( CORBA::is_nil( expr ) ) {
00273 log(Error) <<"Attribute "<< string(attrs[i].in()) << " present in getAttributeList() but not accessible."<<endlog();
00274 continue;
00275 }
00276 AssignableExpression_var as_expr = AssignableExpression::_narrow( expr.in() );
00277
00278
00279 CORBA::String_var tn = expr->getTypeName();
00280 TypeInfo* ti = TypeInfoRepository::Instance()->type( tn.in() );
00281 log(Info) << "Looking up Attribute " << tn.in();
00282 if ( ti && ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ) {
00283 Logger::log() <<": found!"<<endlog();
00284 if ( CORBA::is_nil( as_expr ) ) {
00285 this->attributes()->setValue( ti->buildConstant( attrs[i].in(), ti->getProtocol(ORO_CORBA_PROTOCOL_ID)->proxy( expr.in() ) ) );
00286 }
00287 else {
00288 this->attributes()->setValue( ti->buildAttribute( attrs[i].in(), ti->getProtocol(ORO_CORBA_PROTOCOL_ID)->proxy( expr.in() ) ) );
00289 }
00290 } else {
00291 Logger::log() <<": not found :-("<<endlog();
00292 if ( CORBA::is_nil( as_expr ) )
00293 this->attributes()->setValue( new Constant<CORBA::Any_ptr>( attrs[i].in(), new CORBAExpression<CORBA::Any_ptr>( expr.in() ) ) );
00294 else
00295 this->attributes()->setValue( new Attribute<CORBA::Any_ptr>( attrs[i].in(), new CORBAAssignableExpression<CORBA::Any_ptr>( as_expr.in() ) ) );
00296 }
00297 }
00298
00299 log(Debug) << "Fetching Ports."<<endlog();
00300 DataFlowInterface_var dfact = mtask->ports();
00301 if (dfact) {
00302 DataFlowInterface::PortNames_var objs;
00303 objs = dfact->getPorts();
00304 for ( size_t i=0; i < objs->length(); ++i) {
00305 if (this->ports()->getPort( objs[i].in() ))
00306 continue;
00307 this->ports()->addPort( new CorbaPort( objs[i].in(), dfact.in(), ProxyPOA() ) );
00308 }
00309 }
00310
00311 this->fetchObjects(this, mtask.in() );
00312
00313 log(Debug) << "All Done."<<endlog();
00314 }
00315
00316
00317 void ControlTaskProxy::fetchObjects(OperationInterface* parent, ControlObject_ptr mtask)
00318 {
00319 log(Debug) << "Fetching Objects of "<<parent->getName()<<":"<<endlog();
00320
00321 Corba::ObjectList_var plist = mtask->getObjectList();
00322
00323 for( size_t i =0; i != plist->length(); ++i) {
00324 if ( string( plist[i] ) == "this")
00325 continue;
00326 ControlObject_var cobj = mtask->getObject(plist[i]);
00327 CORBA::String_var descr = cobj->getDescription();
00328
00329 OperationInterface* tobj = this->getObject(std::string(plist[i]));
00330 if (tobj == 0)
00331 tobj = new TaskObject( std::string(plist[i]), std::string(descr.in()) );
00332
00333
00334 log(Debug) << plist[i] << ": fetching Attributes."<<endlog();
00335 AttributeInterface::AttributeNames_var attrs = cobj->attributes()->getAttributeList();
00336
00337 for (size_t j=0; j != attrs->length(); ++j) {
00338 if ( tobj->attributes()->hasAttribute( string(attrs[j].in()) ) )
00339 continue;
00340 Expression_var expr = cobj->attributes()->getAttribute( attrs[j].in() );
00341 if ( CORBA::is_nil( expr ) ) {
00342 log(Error) <<"Attribute "<< string(attrs[j].in()) << " present in getAttributeList() but not accessible."<<endlog();
00343 continue;
00344 }
00345 AssignableExpression_var as_expr = AssignableExpression::_narrow( expr.in() );
00346
00347
00348 CORBA::String_var tn = expr->getTypeName();
00349 TypeInfo* ti = TypeInfoRepository::Instance()->type( tn.in() );
00350 log(Debug) << "Looking up Attribute " << tn.in();
00351 if ( ti && ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ) {
00352 Logger::log() <<": found!"<<endlog();
00353 if ( CORBA::is_nil( as_expr ) ) {
00354 tobj->attributes()->setValue( ti->buildConstant( attrs[i].in(), ti->getProtocol(ORO_CORBA_PROTOCOL_ID)->proxy( expr.in() ) ) );
00355 }
00356 else {
00357 tobj->attributes()->setValue( ti->buildAttribute( attrs[i].in(), ti->getProtocol(ORO_CORBA_PROTOCOL_ID)->proxy( expr.in() ) ) );
00358 }
00359 } else {
00360 Logger::log() <<": not found :-("<<endlog();
00361 if ( CORBA::is_nil( as_expr ) )
00362 tobj->attributes()->setValue( new Constant<CORBA::Any_ptr>( attrs[j].in(), new CORBAExpression<CORBA::Any_ptr>( expr.in() ) ) );
00363 else
00364 tobj->attributes()->setValue( new Attribute<CORBA::Any_ptr>( attrs[j].in(), new CORBAAssignableExpression<CORBA::Any_ptr>( as_expr.in() ) ) );
00365 }
00366 }
00367
00368
00369 log(Debug) << plist[i] << ": fetching Methods."<<endlog();
00370 MethodInterface_var mfact = cobj->methods();
00371 if (mfact) {
00372 MethodList_var objs;
00373 objs = mfact->getMethods();
00374 for ( size_t i=0; i < objs->length(); ++i) {
00375 if (tobj->methods()->hasMember( string(objs[i].in() )))
00376 continue;
00377 tobj->methods()->add( objs[i].in(), new CorbaMethodFactory( objs[i].in(), mfact.in(), ProxyPOA() ) );
00378 }
00379 }
00380
00381 log(Debug) << plist[i] << ": fetching Commands."<<endlog();
00382 CommandInterface_var cfact = cobj->commands();
00383 if (cfact) {
00384 CommandList_var objs;
00385 objs = cfact->getCommands();
00386 for ( size_t i=0; i < objs->length(); ++i) {
00387 if (tobj->commands()->hasMember( string(objs[i].in() )))
00388 continue;
00389 tobj->commands()->add( objs[i].in(), new CorbaCommandFactory( objs[i].in(), cfact.in(), ProxyPOA() ) );
00390 }
00391 }
00392
00393 if (parent->getObject( string(plist[i].in()) ) == 0 )
00394 parent->addObject( tobj );
00395
00396
00397 this->fetchObjects( tobj, cobj.in() );
00398 }
00399 }
00400
00401 bool ControlTaskProxy::InitOrb(int argc, char* argv[] ) {
00402 if ( orb.in() )
00403 return false;
00404
00405 try {
00406
00407 orb =
00408 CORBA::ORB_init (argc, const_cast<char**>(argv),
00409 "" );
00410
00411 CORBA::Object_var poa_object =
00412 orb->resolve_initial_references ("RootPOA");
00413 rootPOA =
00414 PortableServer::POA::_narrow (poa_object.in ());
00415 PortableServer::POAManager_var poa_manager =
00416 rootPOA->the_POAManager ();
00417 poa_manager->activate ();
00418
00419 return true;
00420 }
00421 catch (CORBA::Exception &e) {
00422 log(Error) << "Orb Init : CORBA exception raised!" << Logger::nl;
00423 Logger::log() << e._info().c_str() << endlog();
00424 }
00425 return false;
00426 }
00427
00428 void ControlTaskProxy::DestroyOrb()
00429 {
00430 try {
00431
00432
00433 orb->destroy();
00434 std::cerr <<"Orb destroyed."<<std::endl;
00435 }
00436 catch (CORBA::Exception &e) {
00437 log(Error) << "Orb Init : CORBA exception raised!" << Logger::nl;
00438 Logger::log() << e._info().c_str() << endlog();
00439 }
00440 }
00441
00442
00443 ControlTaskProxy* ControlTaskProxy::Create(std::string name, bool is_ior ) {
00444 if ( CORBA::is_nil(orb) || name.empty() )
00445 return 0;
00446
00447
00448 try {
00449 ControlTaskProxy* ctp = new ControlTaskProxy( name, is_ior );
00450 return ctp;
00451 }
00452 catch( IllegalServer& is ) {
00453 cerr << is.what() << endl;
00454 }
00455 return 0;
00456 }
00457
00458 ControlTaskProxy* ControlTaskProxy::Create(::RTT::Corba::ControlTask_ptr t) {
00459 if ( CORBA::is_nil(orb) ) {
00460 log(Error) << "Can not create proxy when ORB is nill !"<<endlog();
00461 return 0;
00462 }
00463 if ( !t ) {
00464 log(Error) << "Can not create proxy for nill peer !" <<endlog();
00465 return 0;
00466 }
00467
00468
00469
00470 for (PMap::iterator it = proxies.begin(); it != proxies.end(); ++it)
00471 if ( (it->second)->_is_equivalent( t ) )
00472 return it->first;
00473
00474
00475 try {
00476 ControlTaskProxy* ctp = new ControlTaskProxy( t );
00477 return ctp;
00478 }
00479 catch( IllegalServer& is ) {
00480 cerr << is.what() << endl;
00481 }
00482 return 0;
00483 }
00484
00485 bool ControlTaskProxy::start() {
00486 if (mtask)
00487 return mtask->start();
00488 return false;
00489 }
00490
00491 bool ControlTaskProxy::stop() {
00492 if (mtask)
00493 return mtask->stop();
00494 return false;
00495 }
00496
00497 bool ControlTaskProxy::activate() {
00498 if (mtask)
00499 return mtask->activate();
00500 return false;
00501 }
00502
00503 bool ControlTaskProxy::resetError() {
00504 if (mtask)
00505 return mtask->resetError();
00506 return false;
00507 }
00508
00509 bool ControlTaskProxy::isActive() const {
00510 if (mtask)
00511 return mtask->isActive();
00512 return false;
00513 }
00514
00515 bool ControlTaskProxy::isRunning() const {
00516 if (mtask)
00517 return mtask->isRunning();
00518 return false;
00519 }
00520
00521 bool ControlTaskProxy::configure() {
00522 if (mtask)
00523 return mtask->configure();
00524 return false;
00525 }
00526
00527 bool ControlTaskProxy::cleanup() {
00528 if (mtask)
00529 return mtask->cleanup();
00530 return false;
00531 }
00532
00533 bool ControlTaskProxy::isConfigured() const {
00534 if (mtask)
00535 return mtask->isConfigured();
00536 return false;
00537 }
00538
00539 bool ControlTaskProxy::inFatalError() const {
00540 if (mtask)
00541 return mtask->inFatalError();
00542 return false;
00543 }
00544
00545 bool ControlTaskProxy::inRunTimeWarning() const {
00546 if (mtask)
00547 return mtask->inRunTimeWarning();
00548 return false;
00549 }
00550
00551 bool ControlTaskProxy::inRunTimeError() const {
00552 if (mtask)
00553 return mtask->inRunTimeError();
00554 return false;
00555 }
00556
00557 int ControlTaskProxy::getErrorCount() const {
00558 if (mtask)
00559 return mtask->getErrorCount();
00560 return -1;
00561 }
00562
00563 int ControlTaskProxy::getWarningCount() const {
00564 if (mtask)
00565 return mtask->getWarningCount();
00566 return -1;
00567 }
00568
00569 TaskContext::TaskState ControlTaskProxy::getTaskState() const {
00570 if (mtask)
00571 return TaskContext::TaskState( mtask->getTaskState() );
00572 return TaskContext::Init;
00573 }
00574
00575 void ControlTaskProxy::setName(const std::string& n)
00576 {
00577
00578 }
00579
00580 bool ControlTaskProxy::addPeer( TaskContext* peer, std::string alias )
00581 {
00582 if (!mtask)
00583 return false;
00584
00585
00586 ControlTaskProxy* ctp = dynamic_cast<ControlTaskProxy*>( peer );
00587 if (ctp) {
00588 if ( mtask->addPeer( ctp->server(), alias.c_str() ) ) {
00589 this->synchronize();
00590 return true;
00591 }
00592 return false;
00593 }
00594
00595 ControlTaskServer* newpeer = ControlTaskServer::Create(peer);
00596 if ( mtask->addPeer( newpeer->server(), alias.c_str() ) ) {
00597 this->synchronize();
00598 return true;
00599 }
00600 return false;
00601 }
00602
00603 void ControlTaskProxy::removePeer( const std::string& name )
00604 {
00605 if (!mtask)
00606 return;
00607 mtask->removePeer( name.c_str() );
00608 }
00609
00610 void ControlTaskProxy::removePeer( TaskContext* peer )
00611 {
00612 if (!mtask)
00613 return;
00614 mtask->removePeer( peer->getName().c_str() );
00615 }
00616
00617 bool ControlTaskProxy::connectPeers( TaskContext* peer )
00618 {
00619 if (!mtask)
00620 return false;
00621 ControlTaskServer* newpeer = ControlTaskServer::Create(peer);
00622 return mtask->connectPeers( newpeer->server() );
00623 }
00624
00625 void ControlTaskProxy::disconnectPeers( const std::string& name )
00626 {
00627 if (mtask)
00628 mtask->disconnectPeers( name.c_str() );
00629 }
00630
00631 TaskContext::PeerList ControlTaskProxy::getPeerList() const
00632 {
00633 TaskContext::PeerList vlist;
00634 if (mtask) {
00635 Corba::ControlTask::ControlTaskNames_var plist = mtask->getPeerList();
00636 for( size_t i =0; i != plist->length(); ++i)
00637 vlist.push_back( std::string( plist[i] ) );
00638 }
00639 return vlist;
00640 }
00641
00642 bool ControlTaskProxy::hasPeer( const std::string& peer_name ) const
00643 {
00644 return mtask && mtask->hasPeer( peer_name.c_str() );
00645 }
00646
00647 TaskContext* ControlTaskProxy::getPeer(const std::string& peer_name ) const
00648 {
00649 if ( !mtask )
00650 return 0;
00651 Corba::ControlTask_ptr ct = mtask->getPeer( peer_name.c_str() );
00652 if ( !ct )
00653 return 0;
00654 return ControlTaskProxy::Create( ct );
00655 }
00656
00657 Corba::ControlTask_ptr ControlTaskProxy::server() const {
00658 if ( !mtask )
00659 return 0;
00660 return Corba::ControlTask::_duplicate(mtask);
00661 }
00662
00663 #if 0
00664 CosPropertyService::PropertySet_ptr ControlTaskProxy::propertySet() {
00665 if ( !mtask )
00666 return 0;
00667 return mtask->propertySet();
00668 }
00669 #endif
00670
00671 PortableServer::POA_ptr ControlTaskProxy::ProxyPOA() {
00672 if ( !orb.in() )
00673 return 0;
00674 if (!proxy_poa.in() ) {
00675 CORBA::Object_var poa_object =
00676 orb->resolve_initial_references ("RootPOA");
00677
00678
00679
00680
00681
00682
00683 proxy_poa =
00684 PortableServer::POA::_narrow (poa_object.in ());
00685 }
00686
00687 return proxy_poa.in();
00688 }
00689 }}
00690