Orocos Real-Time Toolkit  2.9.0
TaskContextProxy.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Wed Jan 18 14:09:49 CET 2006 TaskContextProxy.cxx
3 
4  TaskContextProxy.cxx - description
5  -------------------
6  begin : Wed January 18 2006
7  copyright : (C) 2006 Peter Soetens
8  email : peter.soetens@fmtc.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 #include "TaskContextProxy.hpp"
39 #include "TaskContextServer.hpp"
40 #include "TaskContextC.h"
42 #include "CorbaLib.hpp"
43 #include "OperationCallerProxy.hpp"
44 
45 #include "../../types/Types.hpp"
46 #include "../../extras/SequentialActivity.hpp"
47 #include "corba.h"
48 #ifdef CORBA_IS_TAO
49 #include "tao/TimeBaseC.h"
50 #include "tao/Messaging/Messaging.h"
51 #include "tao/Messaging/Messaging_RT_PolicyC.h"
52 #include "orbsvcs/CosNamingC.h"
53 #include <ace/String_Base.h>
54 #else
55 #include <omniORB4/Naming.hh>
56 #endif
57 #include <iostream>
58 #include <fstream>
59 #include <string>
60 
61 #include "RemotePorts.hpp"
62 
63 using namespace std;
64 using namespace RTT::detail;
65 
66 namespace RTT
67 {namespace corba
68 {
69  IllegalServer::IllegalServer() : reason("This server does not exist or has the wrong type.") {}
70 
71  IllegalServer::IllegalServer(const std::string& r) : reason(r) {}
72 
74 
75  const char* IllegalServer::what() const throw() { return reason.c_str(); }
76 
77 
78  std::map<TaskContextProxy*, corba::CTaskContext_ptr> TaskContextProxy::proxies;
79 
80  PortableServer::POA_var TaskContextProxy::proxy_poa;
81 
83  {
84  log(Info) << "Terminating TaskContextProxy for " << this->getName() <<endlog();
85  if ( this->properties() ) {
86  deletePropertyBag( *this->properties() );
87  }
88  this->attributes()->clear();
89  for (list<PortInterface*>::iterator it = port_proxies.begin(); it != port_proxies.end(); ++it)
90  delete *it;
91  proxies.erase(this);
92  }
93 
94  TaskContextProxy::TaskContextProxy(std::string name, bool is_ior)
95  : TaskContext("NotFound")
96  {
97  initFromURIOrTaskname(name, is_ior);
98  }
99 
101  {
102 
103  }
104 
105  void TaskContextProxy::initFromURIOrTaskname(string name, bool is_ior)
106  {
107  Logger::In in("TaskContextProxy");
108  this->clear();
109  this->setActivity( new SequentialActivity() );
110  try {
111  if (is_ior) {
112  // Use the first argument to create the task object reference,
113  // in real applications we use the naming service, but let's do
114  // the easy part first!
115  CORBA::Object_var task_object =
116  orb->string_to_object ( name.c_str() );
117 
118  // Now downcast the object reference to the appropriate type
119  mtask = corba::CTaskContext::_narrow (task_object.in ());
120  } else {
121  // NameService
122  CORBA::Object_var rootObj;
123  CosNaming::NamingContext_var rootContext;
124  try {
125  rootObj = orb->resolve_initial_references("NameService");
126  rootContext = CosNaming::NamingContext::_narrow(rootObj);
127  } catch (...) {}
128 
129  if (CORBA::is_nil(rootContext)) {
130  std::string err("TaskContextProxy could not acquire NameService.");
131  log(Error) << err <<endlog();
132  throw IllegalServer(err);
133  }
134  Logger::log() <<Logger::Debug << "TaskContextProxy found CORBA NameService."<<endlog();
135  CosNaming::Name serverName;
136  serverName.length(2);
137  serverName[0].id = CORBA::string_dup("TaskContexts");
138  serverName[1].id = CORBA::string_dup( name.c_str() );
139 
140  // Get object reference
141  CORBA::Object_var task_object = rootContext->resolve(serverName);
142  mtask = corba::CTaskContext::_narrow (task_object.in ());
143  }
144  if ( CORBA::is_nil( mtask ) ) {
145  std::string err("Failed to acquire TaskContextServer '"+name+"'.");
146  Logger::log() << Logger::Error << err <<endlog();
147  throw IllegalServer(err);
148  }
149  CORBA::String_var nm = mtask->getName(); // force connect to object.
150  std::string newname( nm.in() );
151  this->provides()->setName( newname );
152  Logger::log() << Logger::Info << "Successfully connected to TaskContextServer '"+name+"'."<<endlog();
153  proxies[this] = mtask.in();
154  }
155  catch (CORBA::Exception &e) {
156  log(Error)<< "CORBA exception raised when resolving Object !" << endlog();
157  Logger::log() << CORBA_EXCEPTION_INFO(e) << endlog();
158  throw;
159  }
160  catch (IllegalServer& e) {
161  // rethrow
162  throw e;
163  }
164  catch (...) {
165  log(Error) <<"Unknown Exception in TaskContextProxy construction!"<<endlog();
166  throw;
167  }
168 
169  this->synchronize();
170  }
171 
172  TaskContextProxy::TaskContextProxy( ::RTT::corba::CTaskContext_ptr taskc)
173  : TaskContext("CORBAProxy"), mtask( corba::CTaskContext::_duplicate(taskc) )
174  {
175  Logger::In in("TaskContextProxy");
176  this->clear();
177  // We can't use setActivity() since that would check isRunning() first.
178  this->forceActivity( new SequentialActivity );
179  try {
180  CORBA::String_var nm = mtask->getName(); // force connect to object.
181  std::string name( nm.in() );
182  this->provides()->setName( name );
183  proxies[this] = mtask.in();
184  }
185  catch (CORBA::Exception &e) {
186  log(Error) << "CORBA exception raised when creating TaskContextProxy!" << Logger::nl;
187  Logger::log() << CORBA_EXCEPTION_INFO(e) << endlog();
188  }
189  catch (...) {
190  throw;
191  }
192  this->synchronize();
193  }
194 
196  {
197  // Add here the interfaces that need to be synchronised every time a lookup is done.
198  // Detect already added parts of an interface, does not yet detect removed parts...
199  if (CORBA::is_nil(mtask))
200  return;
201 
202  CTaskContextDescription_var tcd = mtask->getCTaskContextDescription();
203 
204  CService_var serv = tcd->mainprovider;
205  synchronizeServices(this->provides(), serv.in(), tcd->mainprovider_description);
206 
207  CServiceRequester_var srq = tcd->mainrequester;
208  synchronizeRequesters(this->requires(), srq, tcd->mainrequester_description);
209 
210  log(Debug) << "All Done."<<endlog();
211  }
212 
213  void TaskContextProxy::synchronizeRequesters(ServiceRequester::shared_ptr parent, CServiceRequester_ptr csrq, const CServiceRequesterDescription & cdescription)
214  {
215  for ( size_t i=0; i < cdescription.operationcallernames.length(); ++i) {
216  if ( parent->getOperationCaller( string(cdescription.operationcallernames[i].in() )))
217  continue; // already added.
218  log(Debug) << "Requiring operation: "<< cdescription.operationcallernames[i].in() <<endlog();
219  parent->addOperationCaller( * new OperationCallerProxy(string(cdescription.operationcallernames[i].in() ), CServiceRequester::_duplicate(csrq) ));
220  }
221 
222  assert(cdescription.children.length() == cdescription.children_descriptions.length());
223  for( size_t i =0; i != cdescription.children.length(); ++i) {
224  CServiceRequester_ptr cobj = cdescription.children[i];
225  ServiceRequester::shared_ptr tobj = this->requires(std::string(cdescription.children_descriptions[i].name));
226 
227  // Recurse:
228  this->synchronizeRequesters(tobj, cobj, cdescription.children_descriptions[i]);
229  }
230  }
231 
232  void TaskContextProxy::synchronizeServices(Service::shared_ptr parent, CService_ptr serv, const CServiceDescription & cdescription)
233  {
234  log(Debug) << "Synchronizing "<<parent->getName()<<" Service:"<<endlog();
235 
236  // Fetch ports
237  this->synchronizePorts(parent, serv, cdescription);
238 
239  // load command and method factories.
240  // methods:
241  log(Debug) << "Synchronizing Operations."<<endlog();
242  for ( size_t i=0; i < cdescription.operations.length(); ++i) {
243  if ( parent->hasMember( string(cdescription.operations[i].name.in() )))
244  continue; // already added.
245  log(Debug) << "Providing operation: "<< cdescription.operations[i].name.in() <<endlog();
246  parent->add( cdescription.operations[i].name.in(), new CorbaOperationCallerFactory( cdescription.operations[i], serv, ProxyPOA() ) );
247  }
248 
249  // first do properties:
250  log(Debug) << "Synchronizing Properties."<<endlog();
251  for (size_t i=0; i != cdescription.properties.length(); ++i) {
252  if ( findProperty( *parent->properties(), string(cdescription.properties[i].name.in()), "." ) )
253  continue; // previously added.
254 // if ( !serv->hasProperty( cdescription.properties[i].name.in() ) ) {
255 // log(Error) <<"Property "<< string(cdescription.properties[i].name.in()) << " present in getPropertyList() but not accessible."<<endlog();
256 // continue;
257 // }
258  // If the type is known, immediately build the correct property and datasource.
259  TypeInfo* ti = TypeInfoRepository::Instance()->type( cdescription.properties[i].type_name.in() );
260 
261  // decode the prefix and property name from the given name:
262  string pname = string( cdescription.properties[i].name.in() );
263  pname = pname.substr( pname.rfind(".") + 1 );
264  string prefix = string( cdescription.properties[i].name.in() );
265  if ( prefix.rfind(".") == string::npos ) {
266  prefix.clear();
267  }
268  else {
269  prefix = prefix.substr( 0, prefix.rfind(".") );
270  }
271 
272  if ( ti && ti->hasProtocol(ORO_CORBA_PROTOCOL_ID)) {
274  assert(ctt);
275  // data source needs full remote path name
276  DataSourceBase::shared_ptr ds = ctt->createPropertyDataSource( serv, cdescription.properties[i].name.in() );
277  storeProperty( *parent->properties(), prefix, ti->buildProperty( pname, cdescription.properties[i].description.in(), ds));
278  log(Debug) << "Looked up Property " << cdescription.properties[i].type_name.in() << " "<< pname <<": created."<<endlog();
279  }
280  else {
281  if ( string("PropertyBag") == cdescription.properties[i].type_name.in() ) {
282  storeProperty(*parent->properties(), prefix, new Property<PropertyBag>( pname, cdescription.properties[i].description.in()) );
283  log(Debug) << "Looked up PropertyBag " << cdescription.properties[i].type_name.in() << " "<< pname <<": created."<<endlog();
284  } else
285  log(Error) << "Looked up Property " << cdescription.properties[i].type_name.in() << " "<< pname <<": type not known. Check your RTT_COMPONENT_PATH ( \""<<getenv("RTT_COMPONENT_PATH")<<" \")."<<endlog();
286  }
287  }
288 
289  log(Debug) << "Synchronizing Attributes."<<endlog();
290  for (size_t i=0; i != cdescription.attributes.length(); ++i) {
291  if ( parent->hasAttribute( string(cdescription.attributes[i].name.in()) ) )
292  continue; // previously added.
293 #if 0
294  if ( !serv->hasAttribute( cdescription.attributes[i].name.in() ) ) {
295  log(Error) <<"Attribute '"<< string(cdescription.attributes[i].name.in()) << "' present in getAttributeList() but not accessible."<<endlog();
296  continue;
297  }
298 #endif
299  // If the type is known, immediately build the correct attribute and datasource,
300  TypeInfo* ti = TypeInfoRepository::Instance()->type( cdescription.attributes[i].type_name.in() );
301  if ( ti && ti->hasProtocol(ORO_CORBA_PROTOCOL_ID) ) {
302  log(Debug) << "Looking up Attribute " << cdescription.attributes[i].type_name.in() <<": found!"<<endlog();
304  assert(ctt);
305  // this function should check itself for const-ness of the remote Attribute:
306  DataSourceBase::shared_ptr ds = ctt->createAttributeDataSource( serv, cdescription.attributes[i].name.in(), cdescription.attributes[i].assignable );
307  if ( cdescription.attributes[i].assignable )
308  parent->setValue( ti->buildAttribute( cdescription.attributes[i].name.in(), ds));
309  else
310  parent->setValue( ti->buildConstant( cdescription.attributes[i].name.in(), ds));
311  } else {
312  log(Error) << "Looking up Attribute '" << cdescription.attributes[i].name.in() << "' of type " << cdescription.attributes[i].type_name.in() << ": ";
313  if (!ti) {
314  log() << ": type not known. Check your RTT_COMPONENT_PATH ( \""<<getenv("RTT_COMPONENT_PATH")<<" \")." << endlog();
315  } else {
316  log() << ": type does not support CORBA (no transport plugin loaded)" << endlog();
317  }
318  }
319  }
320 
321  assert(cdescription.children.length() == cdescription.children_descriptions.length());
322  for( size_t i =0; i != cdescription.children.length(); ++i) {
323  CService_ptr cobj = cdescription.children[i];
324  Service::shared_ptr tobj = parent->provides(std::string(cdescription.children_descriptions[i].name));
325  tobj->doc( cdescription.children_descriptions[i].description.in() );
326 
327  // Recurse:
328  this->synchronizeServices(tobj, cobj, cdescription.children_descriptions[i]);
329  }
330  }
331 
332  void TaskContextProxy::synchronizePorts(Service::shared_ptr parent, CDataFlowInterface_ptr dfact, const CServiceDescription & cdescription)
333  {
334  log(Debug) << "Synchronizing Ports for service "<<parent->getName()<<"."<<endlog();
336  if (dfact) {
337  for ( size_t i=0; i < cdescription.ports.length(); ++i) {
338  if (parent->getPort( cdescription.ports[i].name.in() ))
339  continue; // already added.
340 
341  TypeInfo const* type_info = type_repo->type(cdescription.ports[i].type_name.in());
342  if (!type_info)
343  {
344  log(Warning) << "remote port '" << cdescription.ports[i].name << "' "
345  << " has unknown type " << cdescription.ports[i].type_name << " and cannot be marshalled over CORBA. "
346  << "It is ignored by TaskContextProxy" << endlog();
347  }
348  else if (!type_info->hasProtocol(ORO_CORBA_PROTOCOL_ID))
349  {
350  log(Warning) << "remote port '" << cdescription.ports[i].name << "' "
351  << " has type " << cdescription.ports[i].type_name << " which cannot be marshalled over CORBA. "
352  << "It is ignored by TaskContextProxy" << endlog();
353  }
354  else
355  {
356  PortInterface* new_port;
357  if (cdescription.ports[i].type == RTT::corba::CInput)
358  new_port = new RemoteInputPort( type_info, dfact, cdescription.ports[i].name.in(), ProxyPOA() );
359  else
360  new_port = new RemoteOutputPort( type_info, dfact, cdescription.ports[i].name.in(), ProxyPOA() );
361 
362  new_port->doc(cdescription.ports[i].description.in());
363  parent->addLocalPort(*new_port);
364  port_proxies.push_back(new_port); // see comment in definition of port_proxies
365  }
366  }
367  }
368  }
369 
370 // // Recursively fetch remote objects and create local proxies.
371 // void TaskContextProxy::fetchServices(Service::shared_ptr parent, CService_ptr serv)
372 // {
373 // log(Debug) << "Fetching "<<parent->getName()<<" Service:"<<endlog();
374 
375 // // Fetch ports
376 // this->fetchPorts(parent, serv);
377 
378 // // load command and method factories.
379 // // methods:
380 // log(Debug) << "Fetching Operations."<<endlog();
381 // COperationInterface::COperationList_var objs;
382 // objs = serv->getOperations();
383 // for ( size_t i=0; i < objs->length(); ++i) {
384 // if ( parent->hasMember( string(objs[i].in() )))
385 // continue; // already added.
386 // log(Debug) << "Providing operation: "<< objs[i].in() <<endlog();
387 // parent->add( objs[i].in(), new CorbaOperationCallerFactory( objs[i].in(), serv, ProxyPOA() ) );
388 // }
389 
390 // // first do properties:
391 // log(Debug) << "Fetching Properties."<<endlog();
392 // // a dot-separated list of subbags and items
393 // CConfigurationInterface::CPropertyNames_var props = serv->getPropertyList();
394 
395 // for (size_t i=0; i != props->length(); ++i) {
396 // if ( findProperty( *parent->properties(), string(props[i].name.in()), "." ) )
397 // continue; // previously added.
398 // if ( !serv->hasProperty( props[i].name.in() ) ) {
399 // log(Error) <<"Property "<< string(props[i].name.in()) << " present in getPropertyList() but not accessible."<<endlog();
400 // continue;
401 // }
402 // // If the type is known, immediately build the correct property and datasource.
403 // CORBA::String_var tn = serv->getPropertyTypeName(props[i].name.in());
404 // TypeInfo* ti = TypeInfoRepository::Instance()->type( tn.in() );
405 
406 // // decode the prefix and property name from the given name:
407 // string pname = string( props[i].name.in() );
408 // pname = pname.substr( pname.rfind(".") + 1 );
409 // string prefix = string( props[i].name.in() );
410 // if ( prefix.rfind(".") == string::npos ) {
411 // prefix.clear();
412 // }
413 // else {
414 // prefix = prefix.substr( 0, prefix.rfind(".") );
415 // }
416 
417 // if ( ti && ti->hasProtocol(ORO_CORBA_PROTOCOL_ID)) {
418 // CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>(ti->getProtocol(ORO_CORBA_PROTOCOL_ID));
419 // assert(ctt);
420 // // data source needs full remote path name
421 // DataSourceBase::shared_ptr ds = ctt->createPropertyDataSource( serv, props[i].name.in() );
422 // storeProperty( *parent->properties(), prefix, ti->buildProperty( pname, props[i].description.in(), ds));
423 // log(Debug) << "Looked up Property " << tn.in() << " "<< pname <<": created."<<endlog();
424 // }
425 // else {
426 // if ( string("PropertyBag") == tn.in() ) {
427 // storeProperty(*parent->properties(), prefix, new Property<PropertyBag>( pname, props[i].description.in()) );
428 // log(Debug) << "Looked up PropertyBag " << tn.in() << " "<< pname <<": created."<<endlog();
429 // } else
430 // log(Error) << "Looked up Property " << tn.in() << " "<< pname <<": type not known. Check your RTT_COMPONENT_PATH ( \""<<getenv("RTT_COMPONENT_PATH")<<" \")."<<endlog();
431 // }
432 // }
433 
434 // log(Debug) << "Fetching Attributes."<<endlog();
435 // CConfigurationInterface::CAttributeNames_var attrs = serv->getAttributeList();
436 // for (size_t i=0; i != attrs->length(); ++i) {
437 // if ( parent->hasAttribute( string(attrs[i].in()) ) )
438 // continue; // previously added.
439 // if ( !serv->hasAttribute( attrs[i].in() ) ) {
440 // log(Error) <<"Attribute '"<< string(attrs[i].in()) << "' present in getAttributeList() but not accessible."<<endlog();
441 // continue;
442 // }
443 // // If the type is known, immediately build the correct attribute and datasource,
444 // CORBA::String_var tn = serv->getAttributeTypeName( attrs[i].in() );
445 // TypeInfo* ti = TypeInfoRepository::Instance()->type( tn.in() );
446 // if ( ti && ti->hasProtocol(ORO_CORBA_PROTOCOL_ID) ) {
447 // log(Debug) << "Looking up Attribute " << tn.in() <<": found!"<<endlog();
448 // CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>(ti->getProtocol(ORO_CORBA_PROTOCOL_ID));
449 // assert(ctt);
450 // // this function should check itself for const-ness of the remote Attribute:
451 // DataSourceBase::shared_ptr ds = ctt->createAttributeDataSource( serv, attrs[i].in() );
452 // if ( serv->isAttributeAssignable( attrs[i].in() ) )
453 // parent->setValue( ti->buildAttribute( attrs[i].in(), ds));
454 // else
455 // parent->setValue( ti->buildConstant( attrs[i].in(), ds));
456 // } else {
457 // log(Error) << "Looking up Attribute " << tn.in();
458 // Logger::log() <<": type not known. Check your RTT_COMPONENT_PATH ( \""<<getenv("RTT_COMPONENT_PATH")<<" \")."<<endlog();
459 // }
460 // }
461 
462 // CService::CProviderNames_var plist = serv->getProviderNames();
463 
464 // for( size_t i =0; i != plist->length(); ++i) {
465 // if ( string( plist[i] ) == "this")
466 // continue;
467 // CService_var cobj = serv->getService(plist[i]);
468 // CORBA::String_var descr = cobj->getServiceDescription();
469 
470 // Service::shared_ptr tobj = parent->provides(std::string(plist[i]));
471 // tobj->doc( descr.in() );
472 
473 // // Recurse:
474 // this->fetchServices( tobj, cobj.in() );
475 // }
476 // }
477 
478 // // Fetch remote ports and create local proxies
479 // void TaskContextProxy::fetchPorts(RTT::Service::shared_ptr parent, CDataFlowInterface_ptr dfact)
480 // {
481 // log(Debug) << "Fetching Ports for service "<<parent->getName()<<"."<<endlog();
482 // TypeInfoRepository::shared_ptr type_repo = TypeInfoRepository::Instance();
483 // if (dfact) {
484 // CDataFlowInterface::CPortDescriptions_var objs = dfact->getPortDescriptions();
485 // for ( size_t i=0; i < objs->length(); ++i) {
486 // CPortDescription port = objs[i];
487 // if (parent->getPort( port.name.in() ))
488 // continue; // already added.
489 
490 // TypeInfo const* type_info = type_repo->type(port.type_name.in());
491 // if (!type_info)
492 // {
493 // log(Warning) << "remote port " << port.name
494 // << " has a type that cannot be marshalled over CORBA: " << port.type_name << ". "
495 // << "It is ignored by TaskContextProxy" << endlog();
496 // }
497 // else
498 // {
499 // PortInterface* new_port;
500 // if (port.type == RTT::corba::CInput)
501 // new_port = new RemoteInputPort( type_info, dfact, port.name.in(), ProxyPOA() );
502 // else
503 // new_port = new RemoteOutputPort( type_info, dfact, port.name.in(), ProxyPOA() );
504 
505 // parent->addLocalPort(*new_port);
506 // port_proxies.push_back(new_port); // see comment in definition of port_proxies
507 // }
508 // }
509 // }
510 // }
511 
513  {
514  try {
515  // Destroy the POA, waiting until the destruction terminates
516  //poa->destroy (1, 1);
517  if (orb) {
518  orb->destroy();
519  rootPOA = 0;
520  orb = 0;
521  std::cerr <<"Orb destroyed."<<std::endl;
522  }
523  }
524  catch (CORBA::Exception &e) {
525  log(Error) << "Orb Init : CORBA exception raised!" << Logger::nl;
526  Logger::log() << CORBA_EXCEPTION_INFO(e) << endlog();
527  }
528  }
529 
530  TaskContextProxy* TaskContextProxy::Create(std::string name, bool is_ior /*=false*/) {
531  if ( CORBA::is_nil(orb) ) {
532  log(Error) << "Won't create a proxy for '"<<name<<"' : orb is nill. Call TaskContextProxy::InitOrb(argc, argv); before TaskContextProxy::Create()." <<endlog();
533  return 0;
534  }
535  if ( name.empty() ) {
536  log(Error) << "Can't create a proxy with an empty name." <<endlog();
537  return 0;
538  }
539  // create new:
540  try {
541  TaskContextProxy* ctp = new TaskContextProxy( name, is_ior );
542  return ctp;
543  }
544  catch( IllegalServer& is ) {
545  log(Error) << is.what() << endlog();
546  }
547  catch (CORBA::Exception &e) {
548  log(Error) << "TaskContextProxy::Create: CORBA exception raised!" << Logger::nl << CORBA_EXCEPTION_INFO(e) << endlog();
549  }
550  return 0;
551  }
552 
554  if ( CORBA::is_nil(orb) ) {
555  log(Error) << "Won't create a proxy for '"<<name<<"' : orb is nill. Call TaskContextProxy::InitOrb(argc, argv); before TaskContextProxy::Create()." <<endlog();
556  return 0;
557  }
558  if ( name.empty() ) {
559  log(Error) << "Can't create a proxy with an empty file name." <<endlog();
560  return 0;
561  }
562 
563  // create new:
564  ifstream namestream( name.c_str() );
565  string ior;
566  namestream >> ior;
567  return Create( ior, true);
568  }
569 
570  TaskContext* TaskContextProxy::Create(::RTT::corba::CTaskContext_ptr t, bool force_remote) {
571  Logger::In in("TaskContextProxy::Create");
572  if ( CORBA::is_nil(orb) ) {
573  log(Error) << "Can not create proxy when ORB is nill !"<<endlog();
574  return 0;
575  }
576  if ( CORBA::is_nil(t) ) {
577  log(Error) << "Can not create proxy for nill peer !" <<endlog();
578  return 0;
579  }
580 
581  // proxy present for this object ?
582  // is_equivalent is actually our best try.
583  for (PMap::iterator it = proxies.begin(); it != proxies.end(); ++it)
584  if ( (it->second)->_is_equivalent( t ) ) {
585  log(Debug) << "Existing proxy found !" <<endlog();
586  return it->first;
587  }
588 
589  // Check if the CTaskContext is actually a local TaskContext
590  if (! force_remote)
591  {
592  for (TaskContextServer::ServerMap::iterator it = TaskContextServer::servers.begin(); it != TaskContextServer::servers.end(); ++it)
593  if ( it->second->server()->_is_equivalent( t ) ) {
594  log(Debug) << "Local server found !" <<endlog();
595  return it->first;
596  }
597  }
598 
599  log(Debug) << "No local taskcontext found..." <<endlog();
600  // create new:
601  try {
602  TaskContextProxy* ctp = new TaskContextProxy( t );
603  return ctp;
604  }
605  catch( IllegalServer& is ) {
606  log(Error) << is.what() << endlog();
607  }
608  catch (CORBA::Exception &e) {
609  log(Error) << "TaskContextProxy::Create: CORBA exception raised!" << Logger::nl << CORBA_EXCEPTION_INFO(e) << endlog();
610  }
611 
612  return 0;
613  }
614 
616  try {
617  if (! CORBA::is_nil(mtask) )
618  return mtask->start();
619  } catch(...) {
620  mtask = CTaskContext::_nil();
621  this->setName("NotFound");
622  this->clear();
623  }
624  return false;
625  }
626 
628  try {
629  if (! CORBA::is_nil(mtask) )
630  return mtask->stop();
631  } catch(...) {
632  mtask = CTaskContext::_nil();
633  this->setName("NotFound");
634  this->clear();
635  }
636  return false;
637  }
638 
640  {
641  try {
642  if (! CORBA::is_nil(mtask) )
643  return mtask->recover();
644  } catch(...) {
645  mtask = CTaskContext::_nil();
646  this->setName("NotFound");
647  this->clear();
648  }
649  return false;
650  }
651 
652 
654  try {
655  if (! CORBA::is_nil(mtask) )
656  return mtask->activate();
657  } catch(...) {
658  mtask = CTaskContext::_nil();
659  this->setName("NotFound");
660  this->clear();
661  }
662  return false;
663  }
664 
666  try {
667  if (! CORBA::is_nil(mtask) )
668  return mtask->isActive();
669  } catch(...) {
670  mtask = CTaskContext::_nil();
671  }
672  return false;
673  }
674 
676  try {
677  if (! CORBA::is_nil(mtask) )
678  return mtask->isRunning();
679  } catch(...) {
680  mtask = CTaskContext::_nil();
681  }
682  return false;
683  }
684 
686  try {
687  if (! CORBA::is_nil(mtask) )
688  return mtask->configure();
689  } catch(...) {
690  mtask = CTaskContext::_nil();
691  this->setName("NotFound");
692  this->clear();
693  }
694  return false;
695  }
696 
698  try {
699  if (! CORBA::is_nil(mtask) )
700  return mtask->cleanup();
701  } catch(...) {
702  mtask = CTaskContext::_nil();
703  this->setName("NotFound");
704  this->clear();
705  }
706  return false;
707  }
708 
710  try {
711  if (! CORBA::is_nil(mtask) )
712  return mtask->isConfigured();
713  } catch(...) {
714  mtask = CTaskContext::_nil();
715  }
716  return false;
717  }
718 
720  try {
721  if (! CORBA::is_nil(mtask) )
722  return mtask->inFatalError();
723  } catch(...) {
724  mtask = CTaskContext::_nil();
725  }
726  return false;
727  }
728 
730  try {
731  if (! CORBA::is_nil(mtask) )
732  return mtask->inRunTimeError();
733  } catch(...) {
734  mtask = CTaskContext::_nil();
735  }
736  return false;
737  }
738 
740  {
741  try {
742  if (! CORBA::is_nil(mtask) )
743  return mtask->inException();
744  } catch(...) {
745  mtask = CTaskContext::_nil();
746  }
747  return false;
748  }
749 
750 
752  try {
753  if (! CORBA::is_nil(mtask) )
754  return TaskContext::TaskState( mtask->getTaskState() );
755  } catch(...) {
756  mtask = CTaskContext::_nil();
757  }
758  return TaskContext::Init;
759  }
760 
761  void TaskContextProxy::setName(const std::string& n)
762  {
763  //mtask->setName( n.c_str() );
764  }
765 
766  bool TaskContextProxy::addPeer( TaskContext* peer, std::string alias /*= ""*/ )
767  {
768  try {
769  if (CORBA::is_nil(mtask))
770  return false;
771 
772  // if peer is a proxy, add the proxy, otherwise, create new server.
773  TaskContextProxy* ctp = dynamic_cast<TaskContextProxy*>( peer );
774  if (ctp) {
775  if ( mtask->addPeer( ctp->server(), alias.c_str() ) ) {
776  this->synchronize();
777  return true;
778  }
779  return false;
780  }
781  // no server yet, create it.
783  if ( mtask->addPeer( newpeer->server(), alias.c_str() ) ) {
784  this->synchronize();
785  return true;
786  }
787  } catch(...) {
788  mtask = CTaskContext::_nil();
789  this->setName("NotFound");
790  this->clear();
791  }
792  return false;
793  }
794 
795  void TaskContextProxy::removePeer( const std::string& name )
796  {
797  try {
798  if (CORBA::is_nil(mtask))
799  return;
800  mtask->removePeer( name.c_str() );
801  } catch(...) {
802  mtask = CTaskContext::_nil();
803  this->setName("NotFound");
804  this->clear();
805  }
806  }
807 
809  {
810  try {
811  if (CORBA::is_nil(mtask))
812  return;
813  mtask->removePeer( peer->getName().c_str() );
814  } catch(...) {
815  mtask = CTaskContext::_nil();
816  this->setName("NotFound");
817  this->clear();
818  }
819  }
820 
822  {
823  try {
824  if (CORBA::is_nil(mtask))
825  return false;
827  return mtask->connectPeers( newpeer->server() );
828  } catch(...) {
829  mtask = CTaskContext::_nil();
830  this->setName("NotFound");
831  this->clear();
832  }
833  return false;
834  }
835 
836  void TaskContextProxy::disconnectPeers( const std::string& name )
837  {
838  try {
839  if (! CORBA::is_nil(mtask) )
840  mtask->disconnectPeers( name.c_str() );
841  } catch(...) {
842  mtask = CTaskContext::_nil();
843  this->setName("NotFound");
844  this->clear();
845  }
846  }
847 
849  {
850 
851  TaskContext::PeerList vlist;
852  try {
853  if (! CORBA::is_nil(mtask) ) {
854  corba::CTaskContext::CPeerNames_var plist = mtask->getPeerList();
855  for( size_t i =0; i != plist->length(); ++i)
856  vlist.push_back( std::string( plist[i] ) );
857  }
858  } catch(...) {
859  mtask = CTaskContext::_nil();
860  }
861  return vlist;
862  }
863 
864  bool TaskContextProxy::hasPeer( const std::string& peer_name ) const
865  {
866  try {
867  if (! CORBA::is_nil(mtask))
868  return mtask->hasPeer( peer_name.c_str() );
869  } catch(...) {
870  mtask = CTaskContext::_nil();
871  }
872  return false;
873  }
874 
875  TaskContext* TaskContextProxy::getPeer(const std::string& peer_name ) const
876  {
877  try {
878  if (CORBA::is_nil(mtask))
879  return 0;
880  corba::CTaskContext_ptr ct = mtask->getPeer( peer_name.c_str() );
881  if ( CORBA::is_nil(ct) )
882  return 0;
883  return TaskContextProxy::Create( ct );
884  } catch(...) {
885  mtask = CTaskContext::_nil();
886  }
887  return 0;
888  }
889 
891  {
892  try {
893  if (CORBA::is_nil(mtask))
894  return false;
896  return mtask->connectPorts( newpeer->server() );
897  } catch(...) {
898  mtask = CTaskContext::_nil();
899  this->setName("NotFound");
900  this->clear();
901  }
902  return false;
903  }
904 
906  {
907  try {
908  if (CORBA::is_nil(mtask))
909  return false;
911  return mtask->connectServices( newpeer->server() );
912  } catch(...) {
913  mtask = CTaskContext::_nil();
914  this->setName("NotFound");
915  this->clear();
916  }
917  return false;
918  }
919 
921  {
922  if (CORBA::is_nil(mtask)) {
923  this->clear();
924  return false;
925  }
926  try {
927  mtask->getName(); // basic check
928  return true;
929  } catch(...) {
930  // we could also try to re-establish the connection in case of naming...
931  this->clear();
932  mtask = CTaskContext::_nil();
933  }
934  return false;
935  }
936 
937  corba::CTaskContext_ptr TaskContextProxy::server() const {
938  if ( CORBA::is_nil(mtask) )
939  return CTaskContext::_nil();
940  return mtask.in();
941  }
942 
943  PortableServer::POA_ptr TaskContextProxy::ProxyPOA() {
944  if ( CORBA::is_nil(orb) )
945  return PortableServer::POA::_nil();
946  if ( CORBA::is_nil(proxy_poa) ) {
947  CORBA::Object_var poa_object =
948  orb->resolve_initial_references ("RootPOA");
949 
950  // new POA for the proxies:
951  // Use default manager, is already activated !
952  //PortableServer::POAManager_var proxy_manager = poa->the_POAManager ();
953  //CORBA::PolicyList pol;
954  //proxy_poa = poa->create_POA( "ProxyPOA", proxy_manager, pol );
955  proxy_poa =
956  PortableServer::POA::_narrow (poa_object.in ());
957  }
958  // note: do not use _retn(): user must duplicate in constructor.
959  return proxy_poa.in();
960  }
961 }}
962 
This class manages the creation of TaskContext Corba Servers and a Corba Object Request Broker (Orb) ...
static PortableServer::POA_var proxy_poa
For now one POA handles all proxies.
virtual void disconnectPeers(const std::string &name)
Remove a two-way connection from this task to a peer task.
Complete description of a Service.
Definition: Service.idl:27
virtual bool isRunning() const
Inspect if the component is in the Running or RunTimeError state.
CConfigurationInterface::CAttributeNames attributes
Definition: Service.idl:33
base::AttributeBase * buildAttribute(std::string name, base::DataSourceBase::shared_ptr source=0) const
Build an Attribute of this type.
Definition: TypeInfo.hpp:222
bool storeProperty(PropertyBag &bag, const std::string &path, base::PropertyBase *item, const std::string &separator)
Stores a property in a bag given a certain path with transfer of ownership.
Service::shared_ptr provides()
Returns this Service.
corba::CTaskContext_ptr server() const
Get the Corba Object of the CTaskContext.
The default, thread-less activity for any newly created TaskContext.
void synchronizePorts(Service::shared_ptr parent, CDataFlowInterface_ptr dfact, const CServiceDescription &cdescription)
virtual bool activate()
This method starts the ExecutionEngine of this component in case it was not running.
virtual bool start()
This method starts the execution of the updateHook() with each trigger or period. ...
static std::ostream & nl(std::ostream &__os)
Insert a newline &#39; &#39; in the ostream.
Definition: Logger.cpp:373
STL namespace.
void forceActivity(base::ActivityInterface *new_act)
Forces the current activity to become new_act, even if this TaskContext is still running.
#define CORBA_EXCEPTION_INFO(x)
Definition: corba.h:68
boost::shared_ptr< ServiceRequester > shared_ptr
virtual bool isActive() const
Inspect if the component&#39;s ExecutionEngine is processing requests.
CDataFlowInterface::CPortDescriptions ports
Definition: Service.idl:34
virtual bool stop()
This method stops the execution of updateHook() of this component.
A local factory for creating remote Corba methods.
virtual void setName(const std::string &n)
virtual bool inException() const
Inspect if the component is in the Exception state.
bool setActivity(base::ActivityInterface *new_act)
Sets the activity of this TaskContext.
basic_ostreams & endl(basic_ostreams &s)
Flush and newline.
Definition: rtstreams.cpp:110
boost::shared_ptr< Service > shared_ptr
Definition: Service.hpp:101
virtual base::DataSourceBase::shared_ptr createPropertyDataSource(CService_ptr serv, const std::string &vname)=0
Create a data source for an attribute or property.
Proxy for a remote output port.
Definition: RemotePorts.hpp:97
ServiceRequester::shared_ptr requires()
Returns the object that manages which methods this Task requires to be implemented by another task...
PropertyBase * findProperty(const PropertyBag &bag, const std::string &nameSequence, const std::string &separator)
This function locates a Property in nested PropertyBags.
corba::CTaskContext_var mtask
Thrown if a server does not exist or has the wrong type.
virtual bool connectServices(TaskContext *peer)
Connects all requires/provides services of this component to these of a peer.
Convenient short notation for every sub-namespace of RTT.
void deletePropertyBag(PropertyBag &target)
This function iterates over a PropertyBag and recursively deletes all Property objects.
const char * what() const
static PortableServer::POA_var rootPOA
The root POA of this process.
This class manages the access of remote TaskContext Corba Servers and a Corba Object Request Broker (...
static TaskContextServer * Create(TaskContext *tc, bool use_naming=true, bool require_name_service=false)
Factory method: create a CORBA server for an existing TaskContext.
void initFromURIOrTaskname(std::string location, bool is_ior)
initializes the class from a stringified ior or taskname in NameServer.
base::AttributeBase * buildConstant(std::string name, base::DataSourceBase::shared_ptr source, int sizehint) const
Build a non modifyable instance of this type.
Definition: TypeInfo.hpp:173
COperationInterface::COperationDescriptions operations
Definition: Service.idl:31
static TaskContextProxy * CreateFromFile(std::string filename)
Factory method: create a CORBA Proxy for an existing TaskContextServer.
A property represents a named value of any type with a description.
Definition: Property.hpp:76
bool hasProtocol(int protocol_id) const
Check if this type is transporable over a given protocol.
Definition: TypeInfo.cpp:168
virtual void removePeer(const std::string &name)
Remove a one-way connection from this task to a peer task.
std::vector< std::string > PeerList
A list of Peer TaskContext names.
CServiceRequesterDescriptions children_descriptions
Complete description of a ServiceRequester.
The state during component construction.
Definition: TaskCore.hpp:100
static PortableServer::POA_ptr ProxyPOA()
Returns the default POA for all proxies.
A class for representing a user type, and which can build instances of that type. ...
Definition: TypeInfo.hpp:67
virtual bool hasPeer(const std::string &peer_name) const
Return true if it knows a peer by that name.
TaskState
Describes the different states a component can have.
Definition: TaskCore.hpp:99
base::PropertyBase * buildProperty(const std::string &name, const std::string &desc, base::DataSourceBase::shared_ptr source=0) const
Build a Property of this type.
Definition: TypeInfo.hpp:214
std::list< base::PortInterface * > port_proxies
CDataFlowInterface does not delete ports automatically, because they can then be defined as members o...
virtual PeerList getPeerList() const
Return a standard container which contains all the Peer names of this TaskContext.
static void DestroyOrb()
Invoke this method once to cleanup the orb.
CConfigurationInterface::CPropertyNames properties
Definition: Service.idl:32
virtual TaskState getTaskState() const
Returns the current state of the TaskCore.
virtual bool inFatalError() const
Inspect if the component is in the FatalError state.
TypeTransporter * getProtocol(int protocol_id) const
Returns this type&#39;s transport for a given protocol.
Definition: TypeInfo.cpp:150
virtual bool inRunTimeError() const
Inspect if the component is in the RunTimeError state.
CServiceDescriptions children_descriptions
Definition: Service.idl:37
Notify the Logger in which &#39;module&#39; the message occured.
Definition: Logger.hpp:159
virtual bool ready()
Checks the validity of this TaskContext.
#define ORO_CORBA_PROTOCOL_ID
Definition: CorbaLib.hpp:45
static Logger & log()
As Instance(), but more userfriendly.
Definition: Logger.cpp:117
virtual bool connectPeers(TaskContext *peer)
Add a two-way connection from this task to a peer task.
The TaskContext is the C++ representation of an Orocos component.
Definition: TaskContext.hpp:93
virtual TaskContext * getPeer(const std::string &peer_name) const
Get a pointer to a peer of this task.
virtual bool addPeer(TaskContext *peer, std::string alias="")
Add a one-way connection from this task to a peer task.
virtual bool cleanup()
This method instructs a stopped component to enter the pre-operational state again.
TaskContextProxy()
A Private constructor which does nothing.
Mirrors a remote operation caller in a ServiceRequestor.
boost::intrusive_ptr< DataSourceBase > shared_ptr
Use this type to store a pointer to a DataSourceBase.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
virtual bool configure()
This method instructs the component to (re-)read configuration data and try to enter the Stopped stat...
PortInterface & doc(const std::string &desc)
Set the documentation of this port.
The base class of every data flow port.
Proxy for a remote input port.
boost::shared_ptr< TypeInfoRepository > shared_ptr
virtual bool isConfigured() const
Inspect if the component is configured, i.e.
virtual bool connectPorts(TaskContext *peer)
Add a data flow connection from this task&#39;s ports to a peer&#39;s ports.
void synchronizeRequesters(ServiceRequester::shared_ptr parent, CServiceRequester_ptr csrq, const CServiceRequesterDescription &cdescription)
static TaskContextProxy * Create(std::string name, bool is_ior=false)
Factory method: create a CORBA Proxy for an existing TaskContextServer.
virtual bool recover()
Call this method in a RunTimeError or Exception state to indicate that the run-time error conditions ...
CTaskContext_ptr server() const
Get the Corba Object of this TaskContext.
static CORBA::ORB_var orb
The orb of this process.
virtual const std::string & getName() const
Returns the name of this TaskContext.
Extends the TypeTransporter in order to allow the creation of channel elements or output halves for a...
virtual base::DataSourceBase::shared_ptr createAttributeDataSource(CService_ptr serv, const std::string &vname, bool is_assignable)=0
void synchronizeServices(Service::shared_ptr parent, CService_ptr serv, const CServiceDescription &cdescription)
virtual void clear()
Clear the complete interface of this Component.
A CTaskContext is the main entry point of a distributed component and maps to a RTT::TaskContext.
Definition: TaskContext.idl:45