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