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