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 }