Orocos Real-Time Toolkit  2.8.3
OperationInterfaceI.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 OperationInterfaceI.cpp
3 
4  OperationInterfaceI.cpp - description
5  -------------------
6  begin : Tue September 07 2010
7  copyright : (C) 2010 The SourceWorks
8  email : peter@thesourceworks.com
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 
39 // -*- C++ -*-
40 //
41 // $Id$
42 
43 // **** Code generated by the The ACE ORB (TAO) IDL Compiler ****
44 // TAO and the TAO IDL Compiler have been developed by:
45 // Center for Distributed Object Computing
46 // Washington University
47 // St. Louis, MO
48 // USA
49 // http://www.cs.wustl.edu/~schmidt/doc-center.html
50 // and
51 // Distributed Object Computing Laboratory
52 // University of California at Irvine
53 // Irvine, CA
54 // USA
55 // http://doc.ece.uci.edu/
56 // and
57 // Institute for Software Integrated Systems
58 // Vanderbilt University
59 // Nashville, TN
60 // USA
61 // http://www.isis.vanderbilt.edu/
62 //
63 // Information about TAO is available at:
64 // http://www.cs.wustl.edu/~schmidt/TAO.html
65 
66 // TAO_IDL - Generated from
67 // ../../../ACE_wrappers/TAO/TAO_IDL/be/be_codegen.cpp:1196
68 
69 #include "CorbaLib.hpp"
70 #include "CorbaTypeTransporter.hpp"
71 #include "OperationInterfaceI.h"
72 #include "AnyDataSource.hpp"
73 #include "../../rtt-detail-fwd.hpp"
74 #include "../../internal/OperationCallerC.hpp"
75 #include "../../internal/SendHandleC.hpp"
76 #include "../../Logger.hpp"
77 #include "../../internal/GlobalEngine.hpp"
78 #include "../../plugin/PluginLoader.hpp"
79 
80 using namespace RTT;
81 using namespace RTT::detail;
82 using namespace std;
83 
85 : mhandle(sh), morig(sh), mofp(ofp)
86 {
87  // this will always be correct:
88  for (unsigned int i = 1; i <= mofp->collectArity(); ++i) {
89  const TypeInfo* ti = mofp->getCollectType(i); // retrieve 1..collectArity()
90  assert(ti);
91  cargs.push_back( ti->buildValue() );
92  mhandle.arg( cargs.back() );
93  }
94  assert( mhandle.ready() );
95 }
96 
98 {
99 }
100 
107 bool anysequence_to_sourcevector( CAnyArguments const& anys, vector<DataSourceBase::shared_ptr>& sources) {
108  return false;
109 }
110 
117 bool sourcevector_to_anysequence( vector<DataSourceBase::shared_ptr> const& sources, CAnyArguments & anys ) {
118  bool valid = true;
119  anys.length( sources.size() );
120  for(unsigned int i = 0; i != sources.size(); ++i) {
121  const TypeInfo* ti = sources[i]->getTypeInfo();
123  ctt->updateAny(sources[i], anys[i]);
124  }
125  return valid;
126 }
127 
129  ::RTT::corba::CAnyArguments_out args)
130 {
131  try {
132  SendStatus ss = mhandle.collect();
133  args = new CAnyArguments();
134  if (ss == SendSuccess) {
135  sourcevector_to_anysequence( cargs, *args.ptr() );
136  }
137  return CSendStatus(static_cast<int>(ss) + 2);
138  } catch(std::runtime_error& e) {
139  throw ::RTT::corba::CCallError(e.what());
140  }
141 }
142 
144  ::RTT::corba::CAnyArguments_out args)
145 {
146  try {
147  SendStatus ss = mhandle.collectIfDone();
148  args = new CAnyArguments();
149  if (ss == SendSuccess) {
150  sourcevector_to_anysequence( cargs, *args.ptr() );
151  }
152  return CSendStatus(static_cast<int>(ss) + 2);
153  } catch(std::runtime_error& e) {
154  throw ::RTT::corba::CCallError(e.what());
155  }
156 }
157 
159  void)
160 {
161  return CSendStatus( static_cast<int>(mhandle.collectIfDone()) + 2 );
162 }
163 
165  void)
166 {
167  try {
168  SendStatus ss = mhandle.collectIfDone();
169  // We just copy over the first collectable argument. In
170  // case of a void operation, we will thus return the first
171  // reference argument.
172  if (ss == SendSuccess) {
173  if ( cargs.size() > 0) {
174  CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (cargs[0]->getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID));
175  return ctt->createAny( cargs[0] );
176  }
177  }
178  return new CORBA::Any();
179  } catch(std::runtime_error& e) {
180  throw ::RTT::corba::CCallError(e.what());
181  }
182 }
183 
186 {
187  try {
188  SendHandleC shc(morig);
189  for (unsigned int i = 0; i != mofp->collectArity(); ++i) {
190  const TypeInfo* ti = mofp->getCollectType(i + 1);
191  assert(ti);
193  shc.arg(ctt->createDataSource(&args[i]));
194  }
195  // otherwise, we would block !!!
196  shc.setAutoCollect(false);
197  shc.check();
198  } catch (name_not_found_exception& nnf) {
199  throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str());
200  } catch (wrong_number_of_args_exception& wna) {
201  throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received);
202  } catch (wrong_types_of_args_exception& wta) {
203  throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str());
204  }
205 }
206 
208  void)
209 {
210  PortableServer::POA_var mPOA = _default_POA();
211  PortableServer::ObjectId_var oid = mPOA->servant_to_id(this);
212  mPOA->deactivate_object( oid.in() );
213  return;
214 }
215 
216 // Implementation skeleton constructor
218  : mfact(gmf), mpoa( PortableServer::POA::_duplicate(the_poa)),
219  loadPluginOperation("loadPlugin", &RTT_corba_COperationInterface_i::loadPlugin, this),
220  loadPluginOperationPart(&loadPluginOperation)
221 {
222  loadPluginOperation.doc("Loads a RTT plugin.").arg("plugin_path", "The path to the shared library containing the plugin.");
223 }
224 
226 {
227  return PortableServer::POA::_duplicate(mpoa);
228 }
229 
230 
231 // Implementation skeleton destructor
233 {
234 }
235 
237  void)
238 {
239  RTT::corba::COperationInterface::COperationList_var rlist = new RTT::corba::COperationInterface::COperationList();
240 
241  vector<string> flist = mfact->getNames();
242  flist.push_back(loadPluginOperationPart.getName());
243  rlist->length( flist.size() );
244  size_t drops=0;
245  for (size_t i=0; i != flist.size(); ++i)
246  if ( !mfact->isSynchronous(flist[i]) ) {
247  rlist[i - drops] = CORBA::string_dup( flist[i].c_str() );
248  } else {
249  ++drops;
250  }
251  rlist->length( flist.size() - drops); // we don't show the synchronous operations.
252  return rlist._retn();
253 }
254 
256  const char * operation)
257 {
258  CDescriptions_var ret = new CDescriptions();
259  OperationInterfacePart* mofp = findOperation(operation);
260  // operation found, convert args:
262  ret->length( args.size() );
263  for (size_t i =0; i != args.size(); ++i) {
264  ret[i].name = CORBA::string_dup( args[i].name.c_str() );
265  ret[i].description = CORBA::string_dup( args[i].description.c_str() );
266  ret[i].type = CORBA::string_dup( args[i].type.c_str() );
267  }
268  return ret._retn();
269 }
270 
272  const char * operation)
273 {
274  OperationInterfacePart* mofp = findOperation(operation);
275  return CORBA::string_dup( mofp->resultType().c_str() );
276 }
277 
279  const char* operation,
280  CORBA::UShort nbr)
281 {
282  OperationInterfacePart* mofp = findOperation(operation);
283  if ( nbr > mofp->arity() )
284  throw ::RTT::corba::CWrongArgumentException( nbr, mofp->arity() );
285  return CORBA::string_dup( mofp->getArgumentType(nbr)->getTypeName().c_str() );
286 }
287 
289  const char* operation,
290  CORBA::UShort nbr)
291 {
292  OperationInterfacePart* mofp = findOperation(operation);
293  if ( nbr > mofp->collectArity() )
294  throw ::RTT::corba::CWrongArgumentException( nbr, mofp->collectArity() );
295  return CORBA::string_dup( mofp->getCollectType(nbr)->getTypeName().c_str() );
296 
297 }
298 
300  const char * operation)
301 {
302  OperationInterfacePart* mofp = findOperation(operation);
303  return mofp->arity();
304 }
305 
307  const char * operation)
308 {
309  OperationInterfacePart* mofp = findOperation(operation);
310  return mofp->collectArity();
311 }
312 
314  const char * operation)
315 {
316  OperationInterfacePart* mofp = findOperation(operation);
317  return CORBA::string_dup( mofp->description().c_str() );
318 }
319 
321  const char * operation,
323 {
324  OperationInterfacePart* mofp = findOperation(operation);
325 
326  try {
327  OperationCallerC mc(mofp, operation, internal::GlobalEngine::Instance());
328  for (unsigned int i = 0; i < mofp->arity() && i < args.length(); ++i) {
329  const TypeInfo* ti = mofp->getArgumentType(i+1);
330  assert(ti);
332  if (ctt) {
333  DataSourceBase::shared_ptr ds = ctt->createDataSource(&args[i]);
334  if (ds)
335  mc.arg(ds);
336  else {
337  log(Error) << "Registered transport for type "<< ti->getTypeName()
338  << " could not create data source from Any (argument "<< i+1
339  <<"): calling operation '"<< operation <<"' will fail." <<endlog();
340  }
341  } else {
342  throw wrong_types_of_args_exception(i+1,"type known to CORBA", ti->getTypeName());
343  }
344  }
345  mc.check();
347  throw ::RTT::corba::CNoSuchNameException(operation);
348  } catch (name_not_found_exception& nnf) {
349  throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str());
350  } catch (wrong_number_of_args_exception& wna) {
351  throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received);
352  } catch (wrong_types_of_args_exception& wta) {
353  throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str());
354  }
355 }
356 
358  const char * operation,
359  ::RTT::corba::CAnyArguments & args)
360 {
361  OperationInterfacePart* mofp = findOperation(operation);
362 
363  // convert Corba args to C++ args.
364  try {
365  OperationCallerC orig(mofp, operation, internal::GlobalEngine::Instance());
366  vector<DataSourceBase::shared_ptr> results;
367  for (size_t i =0; i != args.length(); ++i) {
368  const TypeInfo* ti = mofp->getArgumentType( i + 1);
370  // we need to store the results for returning them to caller (args is inout!) after the call()
371  results.push_back( ctt->createDataSource( &args[i] ) );
372  orig.arg( results[i] );
373  }
374  if ( orig.ready() ) {
376  CORBA::Any* retany;
377 
378  // Try to get the return result :
379  const TypeInfo* ti = ds->getTypeInfo();
381  if ( !ctt ) {
382  log(Warning) << "Could not return results of call to " << operation << ": unknown return type by CORBA transport."<<endlog();
383  ds->evaluate(); // equivalent to orig.call()
384  retany = new CORBA::Any();
385  } else {
386  retany = ctt->createAny( ds ); // call evaluate internally
387  }
388 
389  // Return results into args:
390  for (size_t i =0; i != args.length(); ++i) {
391  const TypeInfo* ti = mofp->getArgumentType( i + 1);
393  ctta->updateAny(results[i], args[i]);
394  }
395  return retany;
396  } else {
397  orig.check(); // will throw
398  }
400  throw ::RTT::corba::CNoSuchNameException( operation );
401  } catch ( name_not_found_exception& ) {
402  throw ::RTT::corba::CNoSuchNameException( operation );
403  } catch ( wrong_number_of_args_exception& wna ) {
404  throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received );
405  } catch (wrong_types_of_args_exception& wta ) {
406  throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() );
407  } catch (std::runtime_error& e){
408  throw ::RTT::corba::CCallError(e.what());
409  }
410  return new ::CORBA::Any();
411 }
412 
413 ::RTT::corba::CSendHandle_ptr RTT_corba_COperationInterface_i::sendOperation (
414  const char * operation,
416 {
417  // This implementation is 90% identical to callOperation above, only deviating in the orig.ready() part.
418  OperationInterfacePart* mofp = findOperation(operation);
419 
420  // convert Corba args to C++ args.
421  try {
422  OperationCallerC orig(mofp, operation, internal::GlobalEngine::Instance());
423  for (size_t i =0; i != args.length(); ++i) {
424  const TypeInfo* ti = mofp->getArgumentType( i + 1);
426  orig.arg( ctt->createDataSource( &args[i] ));
427  }
428  if ( orig.ready() ) {
429  SendHandleC resulthandle = orig.send();
430  // we may not destroy the SendHandle, before the operation completes:
431  resulthandle.setAutoCollect(true);
432  // our resulthandle copy makes sure that the resulthandle can return.
433  RTT_corba_CSendHandle_i* ret_i = new RTT_corba_CSendHandle_i( resulthandle, mofp );
434  CSendHandle_var ret = ret_i->_this();
435  ret_i->_remove_ref(); // if POA drops this, it gets cleaned up.
436  return ret._retn();
437  } else {
438  orig.check(); // will throw
439  }
441  throw ::RTT::corba::CNoSuchNameException( operation );
442  } catch ( name_not_found_exception& ) {
443  throw ::RTT::corba::CNoSuchNameException( operation );
444  } catch ( wrong_number_of_args_exception& wna ) {
445  throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received );
446  } catch (wrong_types_of_args_exception& wta ) {
447  throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() );
448  }
449  return CSendHandle::_nil();
450 }
451 
452 RTT::OperationInterfacePart *RTT_corba_COperationInterface_i::findOperation( const char *operation )
453 {
454  string operation_str(operation);
455  OperationInterfacePart* mofp = mfact->getPart(operation_str);
456  if ( !mofp && (operation_str == "loadPlugin") )
457  mofp = &loadPluginOperationPart;
458  if ( !mofp || mfact->isSynchronous(operation_str) )
459  throw ::RTT::corba::CNoSuchNameException( operation );
460  return mofp;
461 }
462 
463 bool RTT_corba_COperationInterface_i::loadPlugin(const string &pluginPath) {
464  return RTT::plugin::PluginLoader::Instance()->loadPlugin(pluginPath, "");
465 }
virtual ::RTT::corba::CSendStatus collect(::RTT::corba::CAnyArguments_out args)
virtual RTT::corba::COperationInterface::COperationList * getOperations(void)
OperationCallerC & arg(base::DataSourceBase::shared_ptr a)
Add a datasource argument to the OperationCaller.
base::DataSourceBase::shared_ptr getCallDataSource()
Get the contained data source for &#39;call&#39;.
virtual ::RTT::corba::CSendStatus collectIfDone(::RTT::corba::CAnyArguments_out args)
Operation< Signature > & doc(const std::string &description)
Document this operation.
Definition: Operation.hpp:128
virtual char * getDescription(const char *operation)
virtual ::RTT::corba::CDescriptions * getArguments(const char *operation)
virtual char * getResultType(const char *operation)
virtual const types::TypeInfo * getArgumentType(unsigned int arg) const =0
Returns the type information of the n&#39;th argument, with argument zero being the return value...
bool ready() const
Returns true if this method is ready for execution.
const std::string & getTypeName() const
Return the type name which was first registered.
Definition: TypeInfo.hpp:82
virtual char * getArgumentType(const char *, CORBA::UShort)
void check()
Checks if this method is ready for calling, will throw if not so.
sequence< any > CAnyArguments
virtual ~RTT_corba_CSendHandle_i(void)
SendHandleC send()
Send the contained method.
virtual ::RTT::corba::CSendStatus checkStatus(void)
Exception thrown when a factory is requested to create an object with an unknown name.
virtual CORBA::Any_ptr createAny(base::DataSourceBase::shared_ptr source) const =0
Evaluate source and create an any which contains the value of source.
STL namespace.
virtual const types::TypeInfo * getCollectType(unsigned int arg) const =0
Returns the type information of the n&#39;th collectable argument.
void setAutoCollect(bool on_off)
When set to &#39;on&#39;, the destruction of this SendHandleC will cause a call to collect() before all data ...
virtual ::CORBA::Any * callOperation(const char *operation,::RTT::corba::CAnyArguments &args)
SendStatus collect()
Collect the contained method.
virtual std::string description() const =0
Returns the description of this operation.
bool isSynchronous(const std::string &name) const
Query if a given operation is limited to sychronous invocation (own component thread) only...
virtual char * getCollectType(const char *, CORBA::UShort)
virtual ::CORBA::Any * ret(void)
SendStatus
Returns the status of a send() or collect() invocation.
Definition: SendStatus.hpp:53
virtual ::CORBA::UShort getCollectArity(const char *operation)
virtual ::CORBA::UShort getArity(const char *operation)
virtual unsigned int arity() const =0
Returns the arity (number of arguments) of this operation.
OperationInterfacePart * getPart(const std::string &name)
Get a previously added part of this factory.
SendHandleC & arg(base::DataSourceBase::shared_ptr a)
Add a datasource argument to the SendHandle.
std::vector< ArgumentDescription > Descriptions
The descriptions of an argumentlist.
Convenient short notation for every sub-namespace of RTT.
A template-less SendHandle manager.
Definition: SendHandleC.hpp:61
bool anysequence_to_sourcevector(CAnyArguments const &anys, vector< DataSourceBase::shared_ptr > &sources)
Helper function to convert a sequence of anys to a vector of data sources.
A template-less manager for OperationCaller calls.
SendStatus collectIfDone()
Collect the contained method.
A class for representing a user type, and which can build instances of that type. ...
Definition: TypeInfo.hpp:66
virtual void checkOperation(const char *operation, const ::RTT::corba::CAnyArguments &args)
bool ready() const
Returns true if this handle is ready for execution.
This class defines the interface for creating operation objects without using C++ templates...
Operation< Signature > & arg(const std::string &name, const std::string &description)
Document an argument of this operation.
Definition: Operation.hpp:137
virtual std::string resultType() const =0
Return the result (return) type of this operation.
Returned when the send() succeeded, but the operation has not yet been executed by the receiving comp...
Definition: SendStatus.hpp:57
PortableServer::POA_ptr _default_POA()
virtual std::string getName() const
Returns the name of this operation.
virtual std::vector< ArgumentDescription > getArgumentList() const =0
Get a description of the desired arguments in the ArgumentDescription format.
TypeTransporter * getProtocol(int protocol_id) const
Returns this type&#39;s transport for a given protocol.
Definition: TypeInfo.cpp:150
std::vector< std::string > getNames() const
Get a list of all the names of the added operations.
RTT_corba_COperationInterface_i(RTT::OperationInterface *mfact, PortableServer::POA_ptr the_poa)
virtual unsigned int collectArity() const =0
Returns the number of collectable arguments of this operation&#39;s function.
#define ORO_CORBA_PROTOCOL_ID
Definition: CorbaLib.hpp:45
virtual base::DataSourceBase::shared_ptr createDataSource(const CORBA::Any *any) const =0
Create a Data Source from an any.
base::DataSourceBase::shared_ptr buildValue() const
Build a internal::ValueDataSource of this type.
Definition: TypeInfo.hpp:229
bool sourcevector_to_anysequence(vector< DataSourceBase::shared_ptr > const &sources, CAnyArguments &anys)
Helper function to convert a vector of data sources to a sequence of anys.
Exception thrown when a factory is requested to create an object, but a wrong argument type was given...
static boost::shared_ptr< PluginLoader > Instance()
Create the instance of the PluginLoader.
Exception thrown when a factory is requested to create an object but the wrong number of arguments wa...
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:51
virtual void checkArguments(const ::RTT::corba::CAnyArguments &args)
RTT_corba_CSendHandle_i(RTT::internal::SendHandleC const &sh, RTT::OperationInterfacePart *ofp)
Holds all exported operations of a component and is able to produce callers for these operations...
virtual ::RTT::corba::CSendHandle_ptr sendOperation(const char *operation, const ::RTT::corba::CAnyArguments &args)
virtual bool updateAny(base::DataSourceBase::shared_ptr source, CORBA::Any &any) const =0
Evaluate source and update an any which contains the value of source.
Exception thrown when a factory is requested to produce an asynchronous object while it is not availa...
sequence< CArgumentDescription > CDescriptions
Extends the TypeTransporter in order to allow the creation of channel elements or output halves for a...