Go to the documentation of this file.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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #include "CorbaLib.hpp"
00070 #include "CorbaTypeTransporter.hpp"
00071 #include "OperationInterfaceI.h"
00072 #include "AnyDataSource.hpp"
00073 #include "../../rtt-detail-fwd.hpp"
00074 #include "../../internal/OperationCallerC.hpp"
00075 #include "../../internal/SendHandleC.hpp"
00076 #include "../../Logger.hpp"
00077 #include "../../internal/GlobalEngine.hpp"
00078
00079 using namespace RTT;
00080 using namespace RTT::detail;
00081 using namespace std;
00082
00083 RTT_corba_CSendHandle_i::RTT_corba_CSendHandle_i (SendHandleC const& sh, OperationInterfacePart* ofp)
00084 : mhandle(sh), morig(sh), mofp(ofp)
00085 {
00086
00087 for (unsigned int i = 1; i <= mofp->collectArity(); ++i) {
00088 const TypeInfo* ti = mofp->getCollectType(i);
00089 assert(ti);
00090 cargs.push_back( ti->buildValue() );
00091 mhandle.arg( cargs.back() );
00092 }
00093 assert( mhandle.ready() );
00094 }
00095
00096 RTT_corba_CSendHandle_i::~RTT_corba_CSendHandle_i (void)
00097 {
00098 }
00099
00106 bool anysequence_to_sourcevector( CAnyArguments const& anys, vector<DataSourceBase::shared_ptr>& sources) {
00107 return false;
00108 }
00109
00116 bool sourcevector_to_anysequence( vector<DataSourceBase::shared_ptr> const& sources, CAnyArguments & anys ) {
00117 bool valid = true;
00118 anys.length( sources.size() );
00119 for(unsigned int i = 0; i != sources.size(); ++i) {
00120 const TypeInfo* ti = sources[i]->getTypeInfo();
00121 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00122 ctt->updateAny(sources[i], anys[i]);
00123 }
00124 return valid;
00125 }
00126
00127 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::collect (
00128 ::RTT::corba::CAnyArguments_out args)
00129 {
00130 try {
00131 SendStatus ss = mhandle.collect();
00132 args = new CAnyArguments();
00133 if (ss == SendSuccess) {
00134 sourcevector_to_anysequence( cargs, *args.ptr() );
00135 }
00136 return CSendStatus(static_cast<int>(ss) + 2);
00137 } catch(std::runtime_error& e) {
00138 throw ::RTT::corba::CCallError(e.what());
00139 }
00140 }
00141
00142 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::collectIfDone (
00143 ::RTT::corba::CAnyArguments_out args)
00144 {
00145 try {
00146 SendStatus ss = mhandle.collectIfDone();
00147 args = new CAnyArguments();
00148 if (ss == SendSuccess) {
00149 sourcevector_to_anysequence( cargs, *args.ptr() );
00150 }
00151 return CSendStatus(static_cast<int>(ss) + 2);
00152 } catch(std::runtime_error& e) {
00153 throw ::RTT::corba::CCallError(e.what());
00154 }
00155 }
00156
00157 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::checkStatus (
00158 void)
00159 {
00160 return CSendStatus( static_cast<int>(mhandle.collectIfDone()) + 2 );
00161 }
00162
00163 ::CORBA::Any * RTT_corba_CSendHandle_i::ret (
00164 void)
00165 {
00166 try {
00167 SendStatus ss = mhandle.collectIfDone();
00168
00169
00170
00171 if (ss == SendSuccess) {
00172 if ( cargs.size() > 0) {
00173 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (cargs[0]->getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID));
00174 return ctt->createAny( cargs[0] );
00175 }
00176 }
00177 return new CORBA::Any();
00178 } catch(std::runtime_error& e) {
00179 throw ::RTT::corba::CCallError(e.what());
00180 }
00181 }
00182
00183 void RTT_corba_CSendHandle_i::checkArguments (
00184 const ::RTT::corba::CAnyArguments & args)
00185 {
00186 try {
00187 SendHandleC shc(morig);
00188 for (unsigned int i = 0; i != mofp->collectArity(); ++i) {
00189 const TypeInfo* ti = mofp->getCollectType(i + 1);
00190 assert(ti);
00191 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID));
00192 shc.arg(ctt->createDataSource(&args[i]));
00193 }
00194
00195 shc.setAutoCollect(false);
00196 shc.check();
00197 } catch (name_not_found_exception& nnf) {
00198 throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str());
00199 } catch (wrong_number_of_args_exception& wna) {
00200 throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received);
00201 } catch (wrong_types_of_args_exception& wta) {
00202 throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str());
00203 }
00204 }
00205
00206 void RTT_corba_CSendHandle_i::dispose (
00207 void)
00208 {
00209 PortableServer::POA_var mPOA = _default_POA();
00210 PortableServer::ObjectId_var oid = mPOA->servant_to_id(this);
00211 mPOA->deactivate_object( oid.in() );
00212 return;
00213 }
00214
00215
00216 RTT_corba_COperationInterface_i::RTT_corba_COperationInterface_i (OperationInterface* gmf, PortableServer::POA_ptr the_poa)
00217 :mfact(gmf), mpoa( PortableServer::POA::_duplicate(the_poa))
00218 {
00219 }
00220
00221 PortableServer::POA_ptr RTT_corba_COperationInterface_i::_default_POA()
00222 {
00223 return PortableServer::POA::_duplicate(mpoa);
00224 }
00225
00226
00227
00228 RTT_corba_COperationInterface_i::~RTT_corba_COperationInterface_i (void)
00229 {
00230 }
00231
00232 ::RTT::corba::COperationInterface::COperationList * RTT_corba_COperationInterface_i::getOperations (
00233 void)
00234 {
00235 RTT::corba::COperationInterface::COperationList_var rlist = new RTT::corba::COperationInterface::COperationList();
00236
00237 vector<string> flist = mfact->getNames();
00238 rlist->length( flist.size() );
00239 size_t drops=0;
00240 for (size_t i=0; i != flist.size(); ++i)
00241 if ( !mfact->isSynchronous(flist[i]) ) {
00242 rlist[i - drops] = CORBA::string_dup( flist[i].c_str() );
00243 } else {
00244 ++drops;
00245 }
00246 rlist->length( flist.size() - drops);
00247 return rlist._retn();
00248 }
00249
00250 ::RTT::corba::CDescriptions * RTT_corba_COperationInterface_i::getArguments (
00251 const char * operation)
00252 {
00253 CDescriptions_var ret = new CDescriptions();
00254 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)))
00255 throw ::RTT::corba::CNoSuchNameException( operation );
00256
00257 OperationInterface::Descriptions args = mfact->getArgumentList( string(operation) );
00258 ret->length( args.size() );
00259 for (size_t i =0; i != args.size(); ++i) {
00260 ret[i].name = CORBA::string_dup( args[i].name.c_str() );
00261 ret[i].description = CORBA::string_dup( args[i].description.c_str() );
00262 ret[i].type = CORBA::string_dup( args[i].type.c_str() );
00263 }
00264 return ret._retn();
00265 }
00266
00267 char * RTT_corba_COperationInterface_i::getResultType (
00268 const char * operation)
00269 {
00270 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00271 throw ::RTT::corba::CNoSuchNameException( operation );
00272 return CORBA::string_dup( mfact->getResultType( string(operation) ).c_str() );
00273 }
00274
00275 char* RTT_corba_COperationInterface_i::getArgumentType(
00276 const char* operation,
00277 CORBA::UShort nbr)
00278 {
00279 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00280 throw ::RTT::corba::CNoSuchNameException( operation );
00281 if ( nbr > mfact->getPart(operation)->arity() )
00282 throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->arity() );
00283 return CORBA::string_dup( mfact->getPart( operation )->getArgumentType(nbr)->getTypeName().c_str() );
00284 }
00285
00286 char* RTT_corba_COperationInterface_i::getCollectType(
00287 const char* operation,
00288 CORBA::UShort nbr)
00289 {
00290 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00291 throw ::RTT::corba::CNoSuchNameException( operation );
00292 if ( nbr > mfact->getPart(operation)->collectArity() )
00293 throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->collectArity() );
00294 return CORBA::string_dup( mfact->getPart( operation )->getCollectType(nbr)->getTypeName().c_str() );
00295
00296 }
00297
00298 ::CORBA::UShort RTT_corba_COperationInterface_i::getArity (
00299 const char * operation)
00300 {
00301 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00302 throw ::RTT::corba::CNoSuchNameException( operation );
00303 return mfact->getPart(operation)->arity();
00304 }
00305
00306 ::CORBA::UShort RTT_corba_COperationInterface_i::getCollectArity (
00307 const char * operation)
00308 {
00309 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00310 throw ::RTT::corba::CNoSuchNameException( operation );
00311 return mfact->getPart(operation)->collectArity();
00312 }
00313
00314 char * RTT_corba_COperationInterface_i::getDescription (
00315 const char * operation)
00316 {
00317 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00318 throw ::RTT::corba::CNoSuchNameException( operation );
00319 return CORBA::string_dup( mfact->getDescription( string(operation) ).c_str() );
00320 }
00321
00322 void RTT_corba_COperationInterface_i::checkOperation (
00323 const char * operation,
00324 const ::RTT::corba::CAnyArguments & args)
00325 {
00326 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00327 throw ::RTT::corba::CNoSuchNameException( operation );
00328 try {
00329 OperationInterfacePart* mofp = mfact->getPart(operation);
00330 OperationCallerC mc(mofp, operation, internal::GlobalEngine::Instance());
00331 for (unsigned int i = 0; i < mofp->arity() && i < args.length(); ++i) {
00332 const TypeInfo* ti = mofp->getArgumentType(i+1);
00333 assert(ti);
00334 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID));
00335 if (ctt) {
00336 DataSourceBase::shared_ptr ds = ctt->createDataSource(&args[i]);
00337 if (ds)
00338 mc.arg(ds);
00339 else {
00340 log(Error) << "Registered transport for type "<< ti->getTypeName()
00341 << " could not create data source from Any (argument "<< i+1
00342 <<"): calling operation '"<< operation <<"' will fail." <<endlog();
00343 }
00344 } else {
00345 throw wrong_types_of_args_exception(i+1,"type known to CORBA", ti->getTypeName());
00346 }
00347 }
00348 mc.check();
00349 } catch (no_asynchronous_operation_exception& ) {
00350 throw ::RTT::corba::CNoSuchNameException(operation);
00351 } catch (name_not_found_exception& nnf) {
00352 throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str());
00353 } catch (wrong_number_of_args_exception& wna) {
00354 throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received);
00355 } catch (wrong_types_of_args_exception& wta) {
00356 throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str());
00357 }
00358 }
00359
00360 ::CORBA::Any * RTT_corba_COperationInterface_i::callOperation (
00361 const char * operation,
00362 ::RTT::corba::CAnyArguments & args)
00363 {
00364 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00365 throw ::RTT::corba::CNoSuchNameException( operation );
00366
00367 try {
00368 OperationCallerC orig(mfact->getPart(operation), operation, internal::GlobalEngine::Instance());
00369 vector<DataSourceBase::shared_ptr> results;
00370 for (size_t i =0; i != args.length(); ++i) {
00371 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1);
00372 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00373
00374 results.push_back( ctt->createDataSource( &args[i] ) );
00375 orig.arg( results[i] );
00376 }
00377 if ( orig.ready() ) {
00378 DataSourceBase::shared_ptr ds = orig.getCallDataSource();
00379 CORBA::Any* retany;
00380
00381
00382 const TypeInfo* ti = ds->getTypeInfo();
00383 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00384 if ( !ctt ) {
00385 log(Warning) << "Could not return results of call to " << operation << ": unknown return type by CORBA transport."<<endlog();
00386 ds->evaluate();
00387 retany = new CORBA::Any();
00388 } else {
00389 retany = ctt->createAny( ds );
00390 }
00391
00392
00393 for (size_t i =0; i != args.length(); ++i) {
00394 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1);
00395 CorbaTypeTransporter* ctta = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00396 ctta->updateAny(results[i], args[i]);
00397 }
00398 return retany;
00399 } else {
00400 orig.check();
00401 }
00402 } catch (no_asynchronous_operation_exception& ) {
00403 throw ::RTT::corba::CNoSuchNameException( operation );
00404 } catch ( name_not_found_exception& ) {
00405 throw ::RTT::corba::CNoSuchNameException( operation );
00406 } catch ( wrong_number_of_args_exception& wna ) {
00407 throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received );
00408 } catch (wrong_types_of_args_exception& wta ) {
00409 throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() );
00410 } catch (std::runtime_error& e){
00411 throw ::RTT::corba::CCallError(e.what());
00412 }
00413 return new ::CORBA::Any();
00414 }
00415
00416 ::RTT::corba::CSendHandle_ptr RTT_corba_COperationInterface_i::sendOperation (
00417 const char * operation,
00418 const ::RTT::corba::CAnyArguments & args)
00419 {
00420
00421 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00422 throw ::RTT::corba::CNoSuchNameException( operation );
00423
00424 try {
00425 OperationCallerC orig(mfact->getPart(operation), operation, internal::GlobalEngine::Instance());
00426 for (size_t i =0; i != args.length(); ++i) {
00427 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1);
00428 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00429 orig.arg( ctt->createDataSource( &args[i] ));
00430 }
00431 if ( orig.ready() ) {
00432 SendHandleC resulthandle = orig.send();
00433
00434 resulthandle.setAutoCollect(true);
00435
00436 RTT_corba_CSendHandle_i* ret_i = new RTT_corba_CSendHandle_i( resulthandle, mfact->getPart(operation) );
00437 CSendHandle_var ret = ret_i->_this();
00438 ret_i->_remove_ref();
00439 return ret._retn();
00440 } else {
00441 orig.check();
00442 }
00443 } catch (no_asynchronous_operation_exception& ) {
00444 throw ::RTT::corba::CNoSuchNameException( operation );
00445 } catch ( name_not_found_exception& ) {
00446 throw ::RTT::corba::CNoSuchNameException( operation );
00447 } catch ( wrong_number_of_args_exception& wna ) {
00448 throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received );
00449 } catch (wrong_types_of_args_exception& wta ) {
00450 throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() );
00451 }
00452 return CSendHandle::_nil();
00453 }